using loops, how to find occurences of each digit in integer interval [n, m]?
for example:
INPUT n,m = [19, 23] = 19, 20, 21, 22, 23
OUTPUT should be:
0 occurences: 1 times
1 occurences: 2 times
2 occurences: 5 times
3 occurences: 1 times etc.
#include <iostream>
using namespace std;
int main()
{
int i, j, z, count, n, m;
cin >>n >>m;
for(int i=0; i<10; i++) // LOOP FOR DIGITS
{
cout << i <<"occurences: ";
count=0;
for(int j=n; j<m; j++) // LOOP INTEGER INTERVAL
{
while (z!=0)
{
z = j % 10; // LAST DIGIT OF FIRST NUMBER IN INTERVAL
if (z == i) count++;
z /= 10;
}
}
cout << count <<" times"<< endl;
}
}
my code returns 0 times for each digit, where is the error?
You don't need to loop over the range 10 times.
int n, m;
cin >> n >> m;
counts = int[10];
for(int i = 0; i < 10; ++i) {
counts[i] = 0;
}
for(int j = n; j <= m; j++) {
int z = j;
do {
int digit = z % 10; // LAST DIGIT OF FIRST NUMBER IN INTERVAL
counts[digit]++;
z /= 10;
} while (z != 0);
}
for(int i = 0; i < 10; ++i) {
cout << i << " occurrences " << counts[i] << " times";
}
You can use std::stringstream to get each digit in a number like so:
constexpr int n = 19;
constexpr int m = 23;
std::array<int, 10> digit_count = {0};
for (int i = n; i <= m; i++)
{
std::stringstream s;
s << i;
unsigned char digit;
while (s >> digit) digit_count[digit - '0']++;
}
Some issues that I see:
z = j % 10;
You need to intialize z outside your while loop to j Also you want to get the mod but not set z to it. try putting the result into a temp variable as opposed to into z.
Your for loop is not inclusive of the last number. for(int j=n; j<m; j++) should be j<=m.
z = j;
while (z!=0)
{
int mod = z % 10; // LAST DIGIT OF FIRST NUMBER IN INTERVAL
if (mod == i) count++;
z /= 10;
}
}
This final code gives the correct result:
#include <iostream>
using namespace std;
int main()
{
int i, j, z, count, n, m;
cin >>n >>m;
for(int i=0; i<10; i++) // LOOP FOR DIGITS
{
cout << i <<" occurences: ";
count=0;
for(int j=n; j<=m; j++) // LOOP INTEGER INTERVAL
{
z = j;
while (z!=0)
{
int mod = z % 10; // LAST DIGIT OF FIRST NUMBER IN INTERVAL
if (mod == i) count++;
z /= 10;
}
}
cout << count <<" times"<< endl;
}
}
19 23
0 occurences: 1 times
1 occurences: 2 times
2 occurences: 5 times
3 occurences: 1 times
4 occurences: 0 times
5 occurences: 0 times
6 occurences: 0 times
7 occurences: 0 times
8 occurences: 0 times
9 occurences: 1 times
Basically, the modulo operation is used to retrieve the least significant digit of any number. Dividing this number with the radix will remove the least significant digit, making the next digit the new least significant digit.
int main(int argc, char *argv[])
{
int radix = 10;
int x, y;
printf("Lower bound: ");
scanf("%d, &x);
printf("Upper bound: ");
scanf("%d, &y);
int digits[radix];
count_digit_occurence(x, y, radix, digits);
int i;
for (i = 0; i < radix; ++i)
{
int occ = digits[i];
printf("%d occurred %d times\n", i, occ);
}
}
void count_digit_occurence(int x, int y, int radix, int digits[radix])
{
int i, n;
for (i = x; i <= y; ++i)
{
n = i;
while (n > 0)
{
++(digits[n % radix]);
n /= radix;
}
}
}
All the answers so far provide algorithms with complexity O(m-n) at best, i.e. linear in the distance from n to m. Here, I provide a method that has logarithmic complexity. The basic idea is to consider the last digit of each number first, then the second last etc.
In order to simplify the code, I change the problem slightly and consider the range [n, m-1], i.e. excluding m.
There are m-n numbers in this range; if this is is a multiple of 10, then each last digit occurs exactly (m-n)/10 times. Otherwise, we must account for the edges. The following routine adds to count unit times the number of occurrences of the last digits in all numbers in the range from n to m-1 inclusive.
void count_last_digits(int n, int m, std::array<int,10> count&, int unit=1)
{
// 1 increment n until it has the same last digit as m
for(int dn=n%10, dm=m%10; n<m && dn!=dm; dn=++n%10)
count[dn] += unit;
// 2 add unit*(m-n)/10 to all counts
if(int cnt = unit*(m-n)/10) // avoid to add nothing
for(int d=0; d!=10; ++d)
count[d] += cnt;
}
Once, we counted the last digits, we count the second last digits etc. First, we need a helper function that just counts the digits of a single number
void count_digits(int x, std::array<int,10> &count, int unit=1)
{
for(; x; x/=10)
count[x%10] += unit;
}
To proceed with the second last digits, we first trim (using this helper function) the interval such that both n and m are multiples of 10, then divide them both by 10, multiply the unit of counting by 10, and recurse
std::array<int,10> count_all_digits(int n, int m)
{
std::array<int,10> count={0};
for(int unit=1; n<m; n/=10,m/=10,unit*=10) {
// count last digits
count_last_digits(n, m, count, unit);
// increment n to the next multiple of 10, but not above m
if(int inc = std::min(10-(n%10), m-n)) {
count_digits(n/10, count, unit*inc);
n += inc;
}
// decrement m to the previous multiple of 10, but not below n
if(int dec = std::min(m%10, m-n)) {
count_digits(m/10, count, unit*dec);
m -= dec; // not really necessary
}
}
return count;
}
The functions count_last_digits() and count_digits() have complexity O(1) and O(ln(x)), respectively. Both are called O(ln(m)) times, so the latter dominates the overall complexity, which is O(ln(m)^2).
Note that these functions assume 0 < n <= m, i.e. n<=0 is not allowed.
Related
For each test case t, I need to input n, the number of elements in an array, and input those elements. Then I have to subtract the smallest element in the array from the sum of all the other elements. Here is my code, but I keep getting TLE:
#include <bits/stdc++.h>
int main(void) {
int t;
std::cin >> t;
while (t --) {
int n, sum = 0, a, k = 100000;
std::cin >> n;
while (n --) {
std::cin >> a;
if (a < k) {
k = a;
} else {
sum += a;
}
n --;
}
std::cout << abs(sum - k) << "\n";
}
}
Sample Input:
3
5
20 16 8 2 13
6
16 9 12 20 15 14
4
2 2 2 2
Sample Output:
55
68
4
In this if statement
if (a < k) {
you are comparing each entered value with the current value of k and if it is less than k you are not adding it to sum.
For example for this sequence of numbers
20 16 8 2 13
20 is less than the initial value of k. So now k is equal to 20 and the number is not added to sum.. The next number 16 is also less than the current value of k. And again it is not added to sum.
You need to sum all numbers and at the same time find the minimum number. And then after the loop subtract the minimal number from sum.
Also this statement
n --;
is redundant.
The program can look the following way
#include <iostream>
int main()
{
unsigned int t = 0;
std::cin >> t;
while ( t-- )
{
unsigned int n = 0;
long long int sum = 0;
int min = 0;
bool first = true;
std::cin >> n;
while ( n-- )
{
int x;
std::cin >> x;
if ( first || x < min )
{
first = false;
min = x;
}
sum += x;
}
std::cout << ( sum < min ? min - sum : sum - min ) << '\n';
}
return 0;
}
For the input
1
5
20 16 8 2 13
the program output is
57
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
Given N three-digit numbers, your task is to find bit score of all N numbers and then print the number of pairs possible based on these calculated bit score.
Rule for calculating bit score from three digit number:
From the 3-digit number,
· extract largest digit and multiply by 11 then
· extract smallest digit multiply by 7 then
· add both the result for getting bit pairs.
Note: - Bit score should be of 2-digits, if above results in a 3-digit bit score, simply ignore most significant digit.
Consider following examples:
Say, number is 286
Largest digit is 8 and smallest digit is 2
So, 8*11+2*7 =102 so ignore most significant bit , So bit score = 02.
Say, Number is 123
Largest digit is 3 and smallest digit is 1
So, 3*11+7*1=40, so bit score is 40.
Rules for making pairs from above calculated bit scores
Condition for making pairs are
· Both bit scores should be in either odd position or even position to be eligible to form a pair.
· Pairs can be only made if most significant digit are same and at most two pair can be made for a given significant digit.
Constraints
N<=500
Input Format
First line contains an integer N, denoting the count of numbers.
Second line contains N 3-digit integers delimited by space
Output
One integer value denoting the number of bit pairs.
Test Case
Explanation
Example 1
Input
8 234 567 321 345 123 110 767 111
Output
3
Explanation
After getting the most and least significant digits of the numbers and applying the formula given in Rule 1 we get the bit scores of the numbers as:
58 12 40 76 40 11 19 18
No. of pair possible are 3:
40 appears twice at odd-indices 3 and 5 respectively. Hence, this is one pair.
12, 11, 18 are at even-indices. Hence, two pairs are possible from these three-bit scores.
Hence total pairs possible is 3
#include <iostream>
#include <vector>
using namespace std;
vector<int> correctBitScores(vector<int>);
vector<int> bitScore(vector<int>);
int findPairs(vector<int>);
int main() {
int a, b;
int pairs = 0;
vector<int> vec;
vector<int> bitscore;
cout << "\nEnter count of nos: ";
cin >> a;
for (int i = 0; i < a; i++) {
cin >> b;
vec.push_back(b);
}
bitscore = bitScore(vec);
pairs = findPairs(bitscore);
cout << "Max pairs = " << pairs;
return 0;
}
vector<int> correctBitScores(vector<int> bis) {
int temp = 0;
for (size_t i = 0; i < bis.size(); i++) {
temp = bis[i];
int count = 0;
while (temp > 0) {
temp = temp / 10;
count++;
}
if (count > 2)
bis[i] = abs(100 - bis[i]);
}
/*cout << "\nCorrected" << endl;
for (int i = 0; i < size(bis); i++) {
cout << bis[i] << endl;
}*/
return bis;
}
int findPairs(vector<int> vec) {
int count = 0;
vector<int> odd;
vector<int> even;
for (size_t i = 0; i < vec.size(); i++)
(i % 2 == 0 ? even.push_back(vec[i]) : odd.push_back(vec[i]));
for (size_t j = 0; j < odd.size(); j++)
for (size_t k = j + 1; k < odd.size(); k++) {
if (odd[j] / 10 == odd[k] / 10) {
count++;
odd.erase(odd.begin()+j);
}
}
for (size_t j = 0; j < even.size(); j++)
for (size_t k = j + 1; k < even.size(); k++) {
if (even[j] / 10 == even[k] / 10) {
count++;
even.erase(even.begin() + j);
}
}
return count;
}
vector<int> bitScore(vector<int> v) {
int temp = 0, rem = 0;
vector<int> bs;
for (size_t i = 0; i < v.size(); i++) {
int max = 0, min = 9;
temp = v[i];
while (temp > 0) {
rem = temp % 10;
if (min > rem)
min = rem;
if (max < rem)
max = rem;
temp = temp / 10;
}
int bscore = (max * 11) + (min * 7);
bs.push_back(bscore);
}
/*cout << "\nBit Scores = " << endl;
for (int i = 0; i < size(bs); i++) {
cout << bs[i] << endl;
}*/
bs = correctBitScores(bs);
return bs;
}
I tried doing it very simple c++ code as per my understanding of Que,can you just verify it more test cases.
#include <bits/stdc++.h>
using namespace std;
int main() {
int n,count=0;
cin>>n;
vector<int>v(n);
for(int i=0;i<n;i++){
cin>>v[i];
string s = to_string(v[i]);
sort(s.begin(),s.end());
int temp = (s[s.length()-1]-'0')*11 + (s[0] - '0')*7;
v[i] = temp%100;
}
unordered_map<int ,vector<int>>o,e;
for(int i=0;i<n;i=i+2){
o[v[i]/10].push_back(i+1);
}
for(int i=1;i<n;i=i+2){
e[v[i]/10].push_back(i+1);
}
count=0;
for(int i=0;i<10;i++){
int os=o[i].size(),es=e[i].size();
if(os==2)
count++;
if(es == 2)
count++;
if(os>2 || es>2)
count += 2;
}
cout<<count;
}
I have to create a program which calculates the factorial of any number, the problem is if I input any number above 20 it just returns that number. What in my else if statement could be causing this and is there a better way to solve this? ( this function is called in main and works if num <= 20)
void factorial() {
//User input for number
long long num;
std::cout << "Input any positive integer to find its factorial: ";
std::cin >> num;
unsigned long long numFact = 1;
if (num <= 20) {
while (num > 0) {
numFact = numFact * num;
num = num - 1;
}
std::cout << numFact;
}
else if (num > 20) {
std::vector<int> multFactorial;
//stores num as seperate elements in vector multFactorial
while (num > 0) {
int remain = num % 10;
num = num / 10;
multFactorial.insert(multFactorial.begin(), remain);
}
std::vector<int> answer;
std::vector<int> answerFinal;
//Manually multiplies elements in multFactorial
//Then adds new vectors created by multiplying to get final answer
//Repeats until factorial is solved
//Ex: 21 * 20; 0 * 1 and 0 * 2 stored as {0 , 0}
//2*1 and 2*2 stored as {4, 2, 0}
//Vectors will be addes to get {4, 2, 0} and then that will be multiplied
by 19 until num = 1
while (num > 1) {
for (int i = multFactorial.size() - 1; i >= 0; i--) {
int remain1 = ((num - 1) % 10) * multFactorial[i];
answer.insert(answer.begin(), remain1);
int remain2 = (((num - 1) / 10) * multFactorial[i]);
answerFinal.insert(answerFinal.begin(), remain2);
}
answerFinal.insert(answerFinal.begin(), 0);
//Adds vectors to get final value seperate as digits
for (int i = multFactorial.size() - 1; i >= 0; i--) {
multFactorial[i] = answer[i] + answerFinal[i];
}
num = num - 1;
}
//Prints what should be the factorial of the number input
for (size_t i = 0; i < multFactorial.size(); i++) {
std::cout << multFactorial[i];
}
}
}
Factorials of large numbers results in huge numbers. This can be accommodated in languages like C, C++ etc by putting the results into arbitrary length strings.
Here is an algorithm for that - similar to yours.
https://www.geeksforgeeks.org/factorial-large-number/
Best advice is to check your code against this.
Use a debugger if you have one and step through the code line by line.
If not print out intermediate results and compare with expected.
EDIT: As per review comment, the code at above ref is similar to below- just in case link is broken in future.
// C++ program to compute factorial of big numbers
#include<iostream>
using namespace std;
// Maximum number of digits in output
#define MAX 100 // change to whatever value you need
int multiply(int x, int res[], int res_size);
// Calculate factorial of large number
void factorial(int n)
{
int res[MAX];
// Initialize result
res[0] = 1;
int res_size = 1;
// Apply factorial formula
for (int x=2; x<=n; x++)
res_size = multiply(x, res, res_size);
// print out the result
cout << "Factorial is \n";
for (int i=res_size-1; i>=0; i--)
cout << res[i];
}
// Multiplies x with the number represented by res[].
// res_size is size of res[] or number of digits in the
// number represented by res[].
int multiply(int x, int res[], int res_size)
{
int carry = 0; // Initialize carry
// One by one multiply n with individual digits of res[]
for (int i=0; i<res_size; i++)
{
int prod = res[i] * x + carry;
// Store last digit of 'prod' in res[]
res[i] = prod % 10;
// Put rest in carry
carry = prod/10;
}
// Put carry in res and increase result size
while (carry)
{
res[res_size] = carry%10;
carry = carry/10;
res_size++;
}
return res_size;
}
// Main program
int main()
{
//put code here to read a number
factorial(50); // take 50 for example
return 0;
}
According to this post, we can get all divisors of a number through the following codes.
for (int i = 1; i <= num; ++i){
if (num % i == 0)
cout << i << endl;
}
For example, the divisors of number 24 are 1 2 3 4 6 8 12 24.
After searching some related posts, I did not find any good solutions. Is there any efficient way to accomplish this?
My solution:
Find all prime factors of the given number through this solution.
Get all possible combinations of those prime factors.
However, it doesn't seem to be a good one.
Factors are paired. 1 and 24, 2 and 12, 3 and 8, 4 and 6.
An improvement of your algorithm could be to iterate to the square root of num instead of all the way to num, and then calculate the paired factors using num / i.
You should really check till square root of num as sqrt(num) * sqrt(num) = num:
Something on these lines:
int square_root = (int) sqrt(num) + 1;
for (int i = 1; i < square_root; i++) {
if (num % i == 0&&i*i!=num)
cout << i << num/i << endl;
if (num % i == 0&&i*i==num)
cout << i << '\n';
}
There is no efficient way in the sense of algorithmic complexity (an algorithm with polynomial complexity) known in science by now. So iterating until the square root as already suggested is mostly as good as you can be.
Mainly because of this, a large part of the currently used cryptography is based on the assumption that it is very time consuming to compute a prime factorization of any given integer.
Here's my code:
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;
#define pii pair<int, int>
#define MAX 46656
#define LMT 216
#define LEN 4830
#define RNG 100032
unsigned base[MAX / 64], segment[RNG / 64], primes[LEN];
#define sq(x) ((x)*(x))
#define mset(x,v) memset(x,v,sizeof(x))
#define chkC(x,n) (x[n>>6]&(1<<((n>>1)&31)))
#define setC(x,n) (x[n>>6]|=(1<<((n>>1)&31)))
// http://zobayer.blogspot.com/2009/09/segmented-sieve.html
void sieve()
{
unsigned i, j, k;
for (i = 3; i<LMT; i += 2)
if (!chkC(base, i))
for (j = i*i, k = i << 1; j<MAX; j += k)
setC(base, j);
primes[0] = 2;
for (i = 3, j = 1; i<MAX; i += 2)
if (!chkC(base, i))
primes[j++] = i;
}
//http://www.geeksforgeeks.org/print-all-prime-factors-of-a-given-number/
vector <pii> factors;
void primeFactors(int num)
{
int expo = 0;
for (int i = 0; primes[i] <= sqrt(num); i++)
{
expo = 0;
int prime = primes[i];
while (num % prime == 0){
expo++;
num = num / prime;
}
if (expo>0)
factors.push_back(make_pair(prime, expo));
}
if ( num >= 2)
factors.push_back(make_pair(num, 1));
}
vector <int> divisors;
void setDivisors(int n, int i) {
int j, x, k;
for (j = i; j<factors.size(); j++) {
x = factors[j].first * n;
for (k = 0; k<factors[j].second; k++) {
divisors.push_back(x);
setDivisors(x, j + 1);
x *= factors[j].first;
}
}
}
int main() {
sieve();
int n, x, i;
cin >> n;
for (int i = 0; i < n; i++) {
cin >> x;
primeFactors(x);
setDivisors(1, 0);
divisors.push_back(1);
sort(divisors.begin(), divisors.end());
cout << divisors.size() << "\n";
for (int j = 0; j < divisors.size(); j++) {
cout << divisors[j] << " ";
}
cout << "\n";
divisors.clear();
factors.clear();
}
}
The first part, sieve() is used to find the prime numbers and put them in primes[] array. Follow the link to find more about that code (bitwise sieve).
The second part primeFactors(x) takes an integer (x) as input and finds out its prime factors and corresponding exponent, and puts them in vector factors[]. For example, primeFactors(12) will populate factors[] in this way:
factors[0].first=2, factors[0].second=2
factors[1].first=3, factors[1].second=1
as 12 = 2^2 * 3^1
The third part setDivisors() recursively calls itself to calculate all the divisors of x, using the vector factors[] and puts them in vector divisors[].
It can calculate divisors of any number which fits in int. Also it is quite fast.
Plenty of good solutions exist for finding all the prime factors of not too large numbers. I just wanted to point out, that once you have them, no computation is required to get all the factors.
if N = p_1^{a}*p_{2}^{b}*p_{3}^{c}.....
Then the number of factors is clearly (a+1)(b+1)(c+1).... since every factor can occur zero up to a times.
e.g. 12 = 2^2*3^1 so it has 3*2 = 6 factors. 1,2,3,4,6,12
======
I originally thought that you just wanted the number of distinct factors. But the same logic applies. You just iterate over the set of numbers corresponding to the possible combinations of exponents.
so int he example above:
00
01
10
11
20
21
gives you the 6 factors.
If you want all divisors to be printed in sorted order
int i;
for(i=1;i*i<n;i++){ /*print all the divisors from 1(inclusive) to
if(n%i==0){ √n (exclusive) */
cout<<i<<" ";
}
}
for( ;i>=1;i--){ /*print all the divisors from √n(inclusive) to
if(n%i==0){ n (inclusive)*/
cout<<(n/i)<<" ";
}
}
If divisors can be printed in any order
for(int j=1;j*j<=n;j++){
if(n%j==0){
cout<<j<<" ";
if(j!=(n/j))
cout<<(n/j)<<" ";
}
}
Both approaches have complexity O(√n)
Here is the Java Implementation of this approach:
public static int countAllFactors(int num)
{
TreeSet<Integer> tree_set = new TreeSet<Integer>();
for (int i = 1; i * i <= num; i+=1)
{
if (num % i == 0)
{
tree_set.add(i);
tree_set.add(num / i);
}
}
System.out.print(tree_set);
return tree_set.size();
}
//Try this,it can find divisors of verrrrrrrrrry big numbers (pretty efficiently :-))
#include<iostream>
#include<cstdio>
#include<cmath>
#include<vector>
#include<conio.h>
using namespace std;
vector<double> D;
void divs(double N);
double mod(double &n1, double &n2);
void push(double N);
void show();
int main()
{
double N;
cout << "\n Enter number: "; cin >> N;
divs(N); // find and push divisors to D
cout << "\n Divisors of "<<N<<": "; show(); // show contents of D (all divisors of N)
_getch(); // used visual studio, if it isn't supported replace it by "getch();"
return(0);
}
void divs(double N)
{
for (double i = 1; i <= sqrt(N); ++i)
{
if (!mod(N, i)) { push(i); if(i*i!=N) push(N / i); }
}
}
double mod(double &n1, double &n2)
{
return(((n1/n2)-floor(n1/n2))*n2);
}
void push(double N)
{
double s = 1, e = D.size(), m = floor((s + e) / 2);
while (s <= e)
{
if (N==D[m-1]) { return; }
else if (N > D[m-1]) { s = m + 1; }
else { e = m - 1; }
m = floor((s + e) / 2);
}
D.insert(D.begin() + m, N);
}
void show()
{
for (double i = 0; i < D.size(); ++i) cout << D[i] << " ";
}
int result_num;
bool flag;
cout << "Number Divisors\n";
for (int number = 1; number <= 35; number++)
{
flag = false;
cout << setw(3) << number << setw(14);
for (int i = 1; i <= number; i++)
{
result_num = number % i;
if (result_num == 0 && flag == true)
{
cout << "," << i;
}
if (result_num == 0 && flag == false)
{
cout << i;
}
flag = true;
}
cout << endl;
}
cout << "Press enter to continue.....";
cin.ignore();
return 0;
}
for (int i = 1; i*i <= num; ++i)
{
if (num % i == 0)
cout << i << endl;
if (num/i!=i)
cout << num/i << endl;
}
for( int i = 1; i * i <= num; i++ )
{
/* upto sqrt is because every divisor after sqrt
is also found when the number is divided by i.
EXAMPLE like if number is 90 when it is divided by 5
then you can also see that 90/5 = 18
where 18 also divides the number.
But when number is a perfect square
then num / i == i therefore only i is the factor
*/
//DIVISORS IN TIME COMPLEXITY sqrt(n)
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int main()
{
ll int n;
cin >> n;
for(ll i = 2; i <= sqrt(n); i++)
{
if (n%i==0)
{
if (n/i!=i)
cout << i << endl << n/i<< endl;
else
cout << i << endl;
}
}
}
#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
#define MOD 1000000007
#define fo(i,k,n) for(int i=k;i<=n;++i)
#define endl '\n'
ll etf[1000001];
ll spf[1000001];
void sieve(){
ll i,j;
for(i=0;i<=1000000;i++) {etf[i]=i;spf[i]=i;}
for(i=2;i<=1000000;i++){
if(etf[i]==i){
for(j=i;j<=1000000;j+=i){
etf[j]/=i;
etf[j]*=(i-1);
if(spf[j]==j)spf[j]=i;
}
}
}
}
void primefacto(ll n,vector<pair<ll,ll>>& vec){
ll lastprime = 1,k=0;
while(n>1){
if(lastprime!=spf[n])vec.push_back(make_pair(spf[n],0));
vec[vec.size()-1].second++;
lastprime=spf[n];
n/=spf[n];
}
}
void divisors(vector<pair<ll,ll>>& vec,ll idx,vector<ll>& divs,ll num){
if(idx==vec.size()){
divs.push_back(num);
return;
}
for(ll i=0;i<=vec[idx].second;i++){
divisors(vec,idx+1,divs,num*pow(vec[idx].first,i));
}
}
void solve(){
ll n;
cin>>n;
vector<pair<ll,ll>> vec;
primefacto(n,vec);
vector<ll> divs;
divisors(vec,0,divs,1);
for(auto it=divs.begin();it!=divs.end();it++){
cout<<*it<<endl;
}
}
int main(){
ios_base::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
sieve();
ll t;cin>>t;
while(t--) solve();
return 0;
}
We can use modified sieve for getting all the factors for all numbers in range [1, N-1].
for (int i = 1; i < N; i++) {
for (int j = i; j < N; j += i) {
ans[j].push_back(i);
}
}
The time complexity is O(N * log(N)) as the sum of harmonic series 1 + 1/2 + 1/3 + ... + 1/N can be approximated to log(N).
More info about time complexity : https://math.stackexchange.com/a/3367064
P.S : Usually in programming problems, the task will include several queries where each query represents a different number and hence precalculating the divisors for all numbers in a range at once would be beneficial as the lookup takes O(1) time in that case.
java 8 recursive (works on HackerRank). This method includes option to sum and return the factors as an integer.
static class Calculator implements AdvancedArithmetic {
public int divisorSum(int n) {
if (n == 1)
return 1;
Set<Integer> set = new HashSet<>();
return divisorSum( n, set, 1);
}
private int divisorSum(int n, Set<Integer> sum, int start){
if ( start > n/2 )
return 0;
if (n%start == 0)
sum.add(start);
start++;
divisorSum(n, sum, start);
int total = 0;
for(int number: sum)
total+=number;
return total +n;
}
}
I'm doing an online challenge and the challenge is the following:
"Kids are playing a game called "Counting digits". For given numbers S and K, they firstly write all numbers between those numbers and then count how many times each digit appears (0,1,2,3,4,5,6,7,8,9). For example, S=767, K=772, numbers will be: 767,768,769,770,771,772
So, 0 will show once (in 770), 1 will show once (in 771) and so on..
Basically, my program have to do the following (given example):
Input:
1 9
(These are numbers 1,2,3,4,5,6,7,8,9)
Output:
0 1 1 1 1 1 1 1 1 1
(0 doesn't show, other numbers show once)."
I'm stuck on this code... out of ideas.
#include <iostream>
using namespace std;
int main()
{
int s,k;
int array[10];
int c0=0,c1=0,c2=0,c3=0,c4=0,c5=0,c6=0,c7=0,c8=0,c9=0;
cin >> s >> k;
int saves = s;
int savek = k;
cout << s%10;
for(int i=s;i<=k;i++)
{
int savei=i;
while(savei!=0)
{
savei=savei%10;
}
}
Any pseudo code/snippet/code/hint is appreciated.
Purely numeric solution to a purely numeric problem:
#include <iostream>
int main()
{
int s, k, i, tmp;
std::cin >> s >> k;
int count[10] = { 0 };
for (i = s; i <= k; i++) {
tmp = i;
do {
count[tmp % 10]++;
tmp /= 10;
} while(tmp);
}
for (i = 0; i < 10; i++) {
std::cout << i << " appears " << count[i] << " times" << std::endl;
}
return 0;
}
My solution is like this:
int main(){
int s,k;
cin >> s >> k;
int numbers[10]={0};
string sum;
for(int i=s;i<=k;i++)
{
sum=to_string(i);
for(int i=0;i<sum.length();i++){
numbers[(int)sum.at(i)-48]++;
}
}
for(int i=0;i<10;i++){
cout<<numbers[i]<<endl;
}
return 0;
}
public static void getDigitsInBook(int n) {
for(int i=0;i<10;i++) {
int x = n,val=0,k=1;
while(x!=0) {
int left = x/10;
int num = x%10;
int right = n%k;
if(i == 0) {
val = val+ (left*k);
}
else if(i<num) {
val = val + ((left+1)*k);
}
else if(i==num) {
val = val + (left*k) + right+1;
}
else {
val = val+ (left*k);
}
k=k*10;
x = n/k;
}
System.out.println(val);
}
}
What you usually do with such tasks is calculating the number between 0 and S and between 0 and K and subtracting those.
How many are between 0 and 767? First count the numbers of the last digit. There are 77 times 0, 1, 2, 3, 4, 5, 6, 7 each and 76 times 8 and 9. More formally, 767/10+1 between 0 and 767%10 and 767/10+1 on the rest. Then calculate the number of occurences of the last digit for 767/10=76, multiply by 10, add 7 times 7 and 6 (for the error on the last one) and do the same for the remaining digits, here 76/10=7. Finally, add the results up.
This solves the problem in O(log_10 K).
try this code:
for(int n=s ; n<=k ; n++)
{
tempN = abs(n);
while(tempN > 0)
{
tempDigit = tempN % 10;
tempN /= 10;
//count tempDigit here
}
}
assuming your variables are ints, "tempN /= 10;" should be no problem.