Here I try to write a program in C++ to find NCR. But I've got a problem in the result. It is not correct. Can you help me find what the mistake is in the program?
#include <iostream>
using namespace std;
int fact(int n){
if(n==0) return 1;
if (n>0) return n*fact(n-1);
};
int NCR(int n,int r){
if(n==r) return 1;
if (r==0&&n!=0) return 1;
else return (n*fact(n-1))/fact(n-1)*fact(n-r);
};
int main(){
int n; //cout<<"Enter A Digit for n";
cin>>n;
int r;
//cout<<"Enter A Digit for r";
cin>>r;
int result=NCR(n,r);
cout<<result;
return 0;
}
Your formula is totally wrong, it's supposed to be fact(n)/fact(r)/fact(n-r), but that is in turn a very inefficient way to compute it.
See Fast computation of multi-category number of combinations and especially my comments on that question. (Oh, and please reopen that question also so I can answer it properly)
The single-split case is actually very easy to handle:
unsigned nChoosek( unsigned n, unsigned k )
{
if (k > n) return 0;
if (k * 2 > n) k = n-k;
if (k == 0) return 1;
int result = n;
for( int i = 2; i <= k; ++i ) {
result *= (n-i+1);
result /= i;
}
return result;
}
Demo: http://ideone.com/aDJXNO
If the result doesn't fit, you can calculate the sum of logarithms and get the number of combinations inexactly as a double. Or use an arbitrary-precision integer library.
I'm putting my solution to the other, closely related question here, because ideone.com has been losing code snippets lately, and the other question is still closed to new answers.
#include <utility>
#include <vector>
std::vector< std::pair<int, int> > factor_table;
void fill_sieve( int n )
{
factor_table.resize(n+1);
for( int i = 1; i <= n; ++i )
factor_table[i] = std::pair<int, int>(i, 1);
for( int j = 2, j2 = 4; j2 <= n; (j2 += j), (j2 += ++j) ) {
if (factor_table[j].second == 1) {
int i = j;
int ij = j2;
while (ij <= n) {
factor_table[ij] = std::pair<int, int>(j, i);
++i;
ij += j;
}
}
}
}
std::vector<unsigned> powers;
template<int dir>
void factor( int num )
{
while (num != 1) {
powers[factor_table[num].first] += dir;
num = factor_table[num].second;
}
}
template<unsigned N>
void calc_combinations(unsigned (&bin_sizes)[N])
{
using std::swap;
powers.resize(0);
if (N < 2) return;
unsigned& largest = bin_sizes[0];
size_t sum = largest;
for( int bin = 1; bin < N; ++bin ) {
unsigned& this_bin = bin_sizes[bin];
sum += this_bin;
if (this_bin > largest) swap(this_bin, largest);
}
fill_sieve(sum);
powers.resize(sum+1);
for( unsigned i = largest + 1; i <= sum; ++i ) factor<+1>(i);
for( unsigned bin = 1; bin < N; ++bin )
for( unsigned j = 2; j <= bin_sizes[bin]; ++j ) factor<-1>(j);
}
#include <iostream>
#include <cmath>
int main(void)
{
unsigned bin_sizes[] = { 8, 1, 18, 19, 10, 10, 7, 18, 7, 2, 16, 8, 5, 8, 2, 3, 19, 19, 12, 1, 5, 7, 16, 0, 1, 3, 13, 15, 13, 9, 11, 6, 15, 4, 14, 4, 7, 13, 16, 2, 19, 16, 10, 9, 9, 6, 10, 10, 16, 16 };
calc_combinations(bin_sizes);
char* sep = "";
for( unsigned i = 0; i < powers.size(); ++i ) {
if (powers[i]) {
std::cout << sep << i;
sep = " * ";
if (powers[i] > 1)
std::cout << "**" << powers[i];
}
}
std::cout << "\n\n";
}
The definition of N choose R is to compute the two products and divide one with the other,
(N * N-1 * N-2 * ... * N-R+1) / (1 * 2 * 3 * ... * R)
However, the multiplications may become too large really quick and overflow existing data type. The implementation trick is to reorder the multiplication and divisions as,
(N)/1 * (N-1)/2 * (N-2)/3 * ... * (N-R+1)/R
It's guaranteed that at each step the results is divisible (for n continuous numbers, one of them must be divisible by n, so is the product of these numbers).
For example, for N choose 3, at least one of the N, N-1, N-2 will be a multiple of 3, and for N choose 4, at least one of N, N-1, N-2, N-3 will be a multiple of 4.
C++ code given below.
int NCR(int n, int r)
{
if (r == 0) return 1;
/*
Extra computation saving for large R,
using property:
N choose R = N choose (N-R)
*/
if (r > n / 2) return NCR(n, n - r);
long res = 1;
for (int k = 1; k <= r; ++k)
{
res *= n - k + 1;
res /= k;
}
return res;
}
A nice way to implement n-choose-k is to base it not on factorial, but on a "rising product" function which is closely related to the factorial.
The rising_product(m, n) multiplies together m * (m + 1) * (m + 2) * ... * n, with rules for handling various corner cases, like n >= m, or n <= 1:
See here for an implementation nCk as well as nPk as a intrinsic functions in an interpreted programming language written in C:
static val rising_product(val m, val n)
{
val acc;
if (lt(n, one))
return one;
if (ge(m, n))
return one;
if (lt(m, one))
m = one;
acc = m;
m = plus(m, one);
while (le(m, n)) {
acc = mul(acc, m);
m = plus(m, one);
}
return acc;
}
val n_choose_k(val n, val k)
{
val top = rising_product(plus(minus(n, k), one), n);
val bottom = rising_product(one, k);
return trunc(top, bottom);
}
val n_perm_k(val n, val k)
{
return rising_product(plus(minus(n, k), one), n);
}
This code doesn't use operators like + and < because it is type generic (the type val represents a value of any kinds, such as various kinds of numbers including "bignum" integers) and because it is written in C (no overloading), and because it is the basis for a Lisp-like language that doesn't have infix syntax.
In spite of that, this n-choose-k implementation has a simple structure that is easy to follow.
Legend: le: less than or equal; ge: greater than or equal; trunc: truncating division; plus: addition, mul: multiplication, one: a val typed constant for the number one.
the line
else return (n*fact(n-1))/fact(n-1)*fact(n-r);
should be
else return (n*fact(n-1))/(fact(r)*fact(n-r));
or even
else return fact(n)/(fact(r)*fact(n-r));
Use double instead of int.
UPDATE:
Your formula is also wrong. You should use fact(n)/fact(r)/fact(n-r)
this is for reference to not to get time limit exceeded while solving nCr in competitive programming,i am posting this as it will be helpful to u as you already got answer for ur question,
Getting the prime factorization of the binomial coefficient is probably the most efficient way to calculate it, especially if multiplication is expensive. This is certainly true of the related problem of calculating factorial (see Click here for example).
Here is a simple algorithm based on the Sieve of Eratosthenes that calculates the prime factorization. The idea is basically to go through the primes as you find them using the sieve, but then also to calculate how many of their multiples fall in the ranges [1, k] and [n-k+1,n]. The Sieve is essentially an O(n \log \log n) algorithm, but there is no multiplication done. The actual number of multiplications necessary once the prime factorization is found is at worst O\left(\frac{n \log \log n}{\log n}\right) and there are probably faster ways than that.
prime_factors = []
n = 20
k = 10
composite = [True] * 2 + [False] * n
for p in xrange(n + 1):
if composite[p]:
continue
q = p
m = 1
total_prime_power = 0
prime_power = [0] * (n + 1)
while True:
prime_power[q] = prime_power[m] + 1
r = q
if q <= k:
total_prime_power -= prime_power[q]
if q > n - k:
total_prime_power += prime_power[q]
m += 1
q += p
if q > n:
break
composite[q] = True
prime_factors.append([p, total_prime_power])
print prime_factors
Recursive function is used incorrectly here. fact() function should be changed into this:
int fact(int n){
if(n==0||n==1) //factorial of both 0 and 1 is 1. Base case.
{
return 1;
}else
return (n*fact(n-1));//recursive call.
};
Recursive call should be made in else part.
NCR() function should be changed into this:
int NCR(int n,int r){
if(n==r) {
return 1;
} else if (r==0&&n!=0) {
return 1;
} else if(r==1)
{
return n;
}
else
{
return fact(n)/(fact(r)*fact(n-r));
}
};
// CPP program To calculate The Value Of nCr
#include <bits/stdc++.h>
using namespace std;
int fact(int n);
int nCr(int n, int r)
{
return fact(n) / (fact(r) * fact(n - r));
}
// Returns factorial of n
int fact(int n)
{
int res = 1;
for (int i = 2; i <= n; i++)
res = res * i;
return res;
}
// Driver code
int main()
{
int n = 5, r = 3;
cout << nCr(n, r);
return 0;
}
Related
decompose(11) must return [1,2,4,10].
Note that there are actually two ways to decompose 11², 11² = 121 = 1 + 4 + 16 + 100 = 1² + 2² + 4² + 10².
For decompose(50) don't return [1, 1, 4, 9, 49] but [1, 3, 5, 8, 49] since [1, 1, 4, 9, 49] doesn't form a strictly increasing sequence.
I created a function but in only some cases provides a strictly increasing sequence all of my solutions add up to the correct number, what changes do i have to make to enable the return of a strictly increasing sequence?
vector<ll> Decomp::decompose(ll n){
ll square = n * n, j = 1, nextterm = n - 1, remainder, sum = 0;
float root;
vector<ll> sequence;
do
{
sequence.push_back(nextterm);
sum = sum + (nextterm * nextterm);
remainder = square - sum;
root = sqrt(remainder - 1);
if (root - (int)root > 0)
{
root = (int)root;
}
j = 1;
nextterm = (int)root;
if (remainder == 1)
{
sequence.push_back(1);
}
} while (root > 0);
reverse(sequence.begin(),sequence.end());
for (int i=0; i < sequence.size(); i++)
{
cout << sequence[i] << endl;
}
}
Here is a simple recursive approach, basically exploring all the possibilities.
It stops once a solution is found.
Output:
11 : 1 2 4 10
50 : 1 3 5 8 49
And the code:
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
bool decompose_dp (long long int sum, long long int k, std::vector<long long int> &seq) {
while (k > 0) {
long long int sump = sum - k*k;
if (sump == 0) {
seq.push_back(k);
return true;
}
if (sump < 0) {
k--;
continue;
}
long long int kp = k-1;
while (kp > 0) {
if (decompose_dp(sump, kp, seq)) {
seq.push_back(k);
return true;
}
kp --;
}
k--;
}
return false;
}
std::vector<long long int> decompose(long long int n){
long long int square = n * n, j = 1, nextterm = n - 1, remainder, sum = 0;
float root;
std::vector<long long int> sequence;
auto check = decompose_dp (n*n, n-1, sequence);
return sequence;
}
void pr (long long int n, const std::vector<long long int> &vec) {
std::cout << n << " : ";
for (auto k: vec) {
std::cout << k << " ";
}
std::cout << "\n";
}
int main() {
long long int n = 11;
auto sequence = decompose (n);
pr (n, sequence);
n = 50;
sequence = decompose (n);
pr (n, sequence);
}
Here's BFS, DFS and brute force in Python. BFS seems slow for input 50. Brute force yielded 91020 different combinations for input 50.
from collections import deque
def bfs(n):
target = n * n
queue = deque([(target, [], 1)])
while queue:
t, seq, i = queue.popleft()
if t == 0:
return seq
if (t == target and i*i < t) or (t != target and i*i <= t):
queue.append((t - i*i, seq[:] + [i], i + 1))
queue.append((t, seq, i + 1))
def dfs(n):
target = n * n
stack = [(target, [], 1)]
while stack:
t, seq, i = stack.pop()
if t == 0:
return seq
if (t == target and i*i < t) or (t != target and i*i <= t):
stack.append((t - i*i, seq[:] + [i], i + 1))
stack.append((t, seq, i + 1))
def brute(n):
target = n * n
stack = [(target, [], 1)]
result = []
while stack:
t, seq, i = stack.pop()
if t == 0:
result.append(seq)
if (t == target and i*i < t) or (t != target and i*i <= t):
stack.append((t - i*i, seq[:] + [i], i + 1))
stack.append((t, seq, i + 1))
return result
print bfs(50) # [1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 15, 16, 18, 19, 20]
print dfs(50) # [30, 40]
#print brute(50)
Question is as follows :
Given two numbers n and k. For each number in the interval [1, n], your task is to calculate its largest divisor that is not divisible by k. Print the sum of all these divisors.
Note: k is always a prime number.
t=3*10^5,1<=n<=10^9, 2<=k<=10^9
My approach toward the question:
for every i in range 1 to n, the required divisors is i itself,only when that i is not a multiple of k.
If that i is multiple of k, then we have to find the greatest divisor of a number and match with k. If it does not match, then this divisor is my answer. otherwise, 2nd largest divisor is my answer.
for example,take n=10 and k=2, required divisors for every i in range 1 to 10 is 1, 1, 3, 1, 5, 3, 7, 1, 9, 5. sum of these divisors are 36. So ans=36.
My code,which works for a few test cases and failed for some.
#include<bits/stdc++.h>
using namespace std;
#define ll long long int
ll div2(ll n, ll k) {
if (n % k != 0 || n == 1) {
return n;
}
else {
for (int i = 2; i * i <= n; i++) {
if (n % i == 0) {
ll aa = n / i;
if (aa % k != 0) {
return aa;
}
}
}
}
return 1;
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int t;
cin >> t;
while (t--) {
ll n, k;
cin >> n >> k;
ll sum = 0, pp;
for (pp = 1; pp <= n; pp++) {
//cout << div2(pp, k);
sum = sum + div2(pp, k);
}
cout << sum << '\n';
}
}
Can someone help me where I am doing wrong or suggest me some faster logic to do this question as some of my test cases is showing TIME LIMIT EXCEED
after looking every possible explanation , i modify my code as follows:
#include<bits/stdc++.h>
using namespace std;
#define ll long long int
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int t;
cin >> t;
while (t--) {
ll n, i;
ll k, sum;
cin >> n >> k;
sum = (n * (n + 1)) / 2;
for (i = k; i <= n; i = i + k) {
ll dmax = i / k;
while (dmax % k == 0) {
dmax = dmax / k;
}
sum = (sum - i) + dmax;
}
cout << sum << '\n';
}
}
But still it is giving TIME LIMIT EXCEED for 3 test cases. Someone please help.
Like others already said, look at the constraints: t=3*10^5,1<=n<=10^9, 2<=k<=10^9.
If your test has a complexity O(n), which computing the sum via a loop has, you'll end up doing a t * n ~ 10^14. That's too much.
This challenge is a math one. You'll need to use two facts:
as you already saw, if i = j * k^s with j%k != 0, the largest divisor is j;
sum_{i=1}^t i = (t * (t+1)) / 2
We start with
S = sum(range(1, n)) = n * (n+1) / 2
then for all number of the form k * x we added too much, let's correct:
S = S - sum(k*x for x in range(1, n/k)) + sum(x for x in range(1, n/k))
= S - (k - 1) * (n/k) * (n/k + 1) / 2
continue for number of the form k^2 * x ... then k^p * x until the sum is empty...
Ok, people start writing code, so here's a small Python function:
def so61867604(n, k):
S = (n * (n+1)) // 2
k_pow = k
while k_pow <= n:
up = n // k_pow
S = S - (k - 1) * (up * (up + 1)) // 2
k_pow *= k
return S
and in action here https://repl.it/repls/OlivedrabKeyProjections
In itself this is more of a mathematical problem:
If cur = [1..n], as you have already noticed, the largest divisor = dmax = cur is, if cur % k != 0, otherwise dmax must be < cur. From k we know that it is at most divisible into other prime numbers... Since we want to make sure that dmax is not divisible by k we can do this with a while loop... whereby this is certainly also more elegantly possible (since dmax must be a prime number again due to the prime factorization).
So this should look like this (without guarantee just typed down - maybe I missed something in my thinking):
#include <iostream>
int main() {
unsigned long long n = 10;
unsigned long long k = 2;
for (auto cur_n = decltype(n){1}; cur_n <= n; cur_n++)
{
if (cur_n % k != 0) {
std::cout << "Largest divisor for " << cur_n << ": " << cur_n << " (SELF)" << std::endl;
} else {
unsigned long long dmax= cur_n/k;
while (dmax%k == 0)
dmax= dmax/k;
std::cout << "Largest divisor for " << cur_n << ": " << dmax<< std::endl;
}
}
}
I wonder if something like this is what One Lyner means.
(Note, this code has two errors in it, which are described in the comments, as well as can be elucidated by One Lyner's new code.)
C++ code:
#include <vector>
#include <iostream>
using namespace std;
#define ll long long int
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int t;
cin >> t;
while (t--) {
ll n;
ll k, _k, result;
vector<ll> powers;
cin >> n >> k;
result = n * (n + 1) / 2;
_k = k;
while (_k <= n) {
powers.push_back(_k);
_k = _k * k;
}
for (ll p : powers) {
ll num_js = n / p;
result -= num_js * (num_js + 1) / 2 * (p - 1);
int i = 0;
while (p * powers[i] <= n) {
result += powers[i] * (p - 1);
i = i + 1;
}
}
cout << result << '\n';
}
}
Here I try to write a program in C++ to find NCR. But I've got a problem in the result. It is not correct. Can you help me find what the mistake is in the program?
#include <iostream>
using namespace std;
int fact(int n){
if(n==0) return 1;
if (n>0) return n*fact(n-1);
};
int NCR(int n,int r){
if(n==r) return 1;
if (r==0&&n!=0) return 1;
else return (n*fact(n-1))/fact(n-1)*fact(n-r);
};
int main(){
int n; //cout<<"Enter A Digit for n";
cin>>n;
int r;
//cout<<"Enter A Digit for r";
cin>>r;
int result=NCR(n,r);
cout<<result;
return 0;
}
Your formula is totally wrong, it's supposed to be fact(n)/fact(r)/fact(n-r), but that is in turn a very inefficient way to compute it.
See Fast computation of multi-category number of combinations and especially my comments on that question. (Oh, and please reopen that question also so I can answer it properly)
The single-split case is actually very easy to handle:
unsigned nChoosek( unsigned n, unsigned k )
{
if (k > n) return 0;
if (k * 2 > n) k = n-k;
if (k == 0) return 1;
int result = n;
for( int i = 2; i <= k; ++i ) {
result *= (n-i+1);
result /= i;
}
return result;
}
Demo: http://ideone.com/aDJXNO
If the result doesn't fit, you can calculate the sum of logarithms and get the number of combinations inexactly as a double. Or use an arbitrary-precision integer library.
I'm putting my solution to the other, closely related question here, because ideone.com has been losing code snippets lately, and the other question is still closed to new answers.
#include <utility>
#include <vector>
std::vector< std::pair<int, int> > factor_table;
void fill_sieve( int n )
{
factor_table.resize(n+1);
for( int i = 1; i <= n; ++i )
factor_table[i] = std::pair<int, int>(i, 1);
for( int j = 2, j2 = 4; j2 <= n; (j2 += j), (j2 += ++j) ) {
if (factor_table[j].second == 1) {
int i = j;
int ij = j2;
while (ij <= n) {
factor_table[ij] = std::pair<int, int>(j, i);
++i;
ij += j;
}
}
}
}
std::vector<unsigned> powers;
template<int dir>
void factor( int num )
{
while (num != 1) {
powers[factor_table[num].first] += dir;
num = factor_table[num].second;
}
}
template<unsigned N>
void calc_combinations(unsigned (&bin_sizes)[N])
{
using std::swap;
powers.resize(0);
if (N < 2) return;
unsigned& largest = bin_sizes[0];
size_t sum = largest;
for( int bin = 1; bin < N; ++bin ) {
unsigned& this_bin = bin_sizes[bin];
sum += this_bin;
if (this_bin > largest) swap(this_bin, largest);
}
fill_sieve(sum);
powers.resize(sum+1);
for( unsigned i = largest + 1; i <= sum; ++i ) factor<+1>(i);
for( unsigned bin = 1; bin < N; ++bin )
for( unsigned j = 2; j <= bin_sizes[bin]; ++j ) factor<-1>(j);
}
#include <iostream>
#include <cmath>
int main(void)
{
unsigned bin_sizes[] = { 8, 1, 18, 19, 10, 10, 7, 18, 7, 2, 16, 8, 5, 8, 2, 3, 19, 19, 12, 1, 5, 7, 16, 0, 1, 3, 13, 15, 13, 9, 11, 6, 15, 4, 14, 4, 7, 13, 16, 2, 19, 16, 10, 9, 9, 6, 10, 10, 16, 16 };
calc_combinations(bin_sizes);
char* sep = "";
for( unsigned i = 0; i < powers.size(); ++i ) {
if (powers[i]) {
std::cout << sep << i;
sep = " * ";
if (powers[i] > 1)
std::cout << "**" << powers[i];
}
}
std::cout << "\n\n";
}
The definition of N choose R is to compute the two products and divide one with the other,
(N * N-1 * N-2 * ... * N-R+1) / (1 * 2 * 3 * ... * R)
However, the multiplications may become too large really quick and overflow existing data type. The implementation trick is to reorder the multiplication and divisions as,
(N)/1 * (N-1)/2 * (N-2)/3 * ... * (N-R+1)/R
It's guaranteed that at each step the results is divisible (for n continuous numbers, one of them must be divisible by n, so is the product of these numbers).
For example, for N choose 3, at least one of the N, N-1, N-2 will be a multiple of 3, and for N choose 4, at least one of N, N-1, N-2, N-3 will be a multiple of 4.
C++ code given below.
int NCR(int n, int r)
{
if (r == 0) return 1;
/*
Extra computation saving for large R,
using property:
N choose R = N choose (N-R)
*/
if (r > n / 2) return NCR(n, n - r);
long res = 1;
for (int k = 1; k <= r; ++k)
{
res *= n - k + 1;
res /= k;
}
return res;
}
A nice way to implement n-choose-k is to base it not on factorial, but on a "rising product" function which is closely related to the factorial.
The rising_product(m, n) multiplies together m * (m + 1) * (m + 2) * ... * n, with rules for handling various corner cases, like n >= m, or n <= 1:
See here for an implementation nCk as well as nPk as a intrinsic functions in an interpreted programming language written in C:
static val rising_product(val m, val n)
{
val acc;
if (lt(n, one))
return one;
if (ge(m, n))
return one;
if (lt(m, one))
m = one;
acc = m;
m = plus(m, one);
while (le(m, n)) {
acc = mul(acc, m);
m = plus(m, one);
}
return acc;
}
val n_choose_k(val n, val k)
{
val top = rising_product(plus(minus(n, k), one), n);
val bottom = rising_product(one, k);
return trunc(top, bottom);
}
val n_perm_k(val n, val k)
{
return rising_product(plus(minus(n, k), one), n);
}
This code doesn't use operators like + and < because it is type generic (the type val represents a value of any kinds, such as various kinds of numbers including "bignum" integers) and because it is written in C (no overloading), and because it is the basis for a Lisp-like language that doesn't have infix syntax.
In spite of that, this n-choose-k implementation has a simple structure that is easy to follow.
Legend: le: less than or equal; ge: greater than or equal; trunc: truncating division; plus: addition, mul: multiplication, one: a val typed constant for the number one.
the line
else return (n*fact(n-1))/fact(n-1)*fact(n-r);
should be
else return (n*fact(n-1))/(fact(r)*fact(n-r));
or even
else return fact(n)/(fact(r)*fact(n-r));
Use double instead of int.
UPDATE:
Your formula is also wrong. You should use fact(n)/fact(r)/fact(n-r)
this is for reference to not to get time limit exceeded while solving nCr in competitive programming,i am posting this as it will be helpful to u as you already got answer for ur question,
Getting the prime factorization of the binomial coefficient is probably the most efficient way to calculate it, especially if multiplication is expensive. This is certainly true of the related problem of calculating factorial (see Click here for example).
Here is a simple algorithm based on the Sieve of Eratosthenes that calculates the prime factorization. The idea is basically to go through the primes as you find them using the sieve, but then also to calculate how many of their multiples fall in the ranges [1, k] and [n-k+1,n]. The Sieve is essentially an O(n \log \log n) algorithm, but there is no multiplication done. The actual number of multiplications necessary once the prime factorization is found is at worst O\left(\frac{n \log \log n}{\log n}\right) and there are probably faster ways than that.
prime_factors = []
n = 20
k = 10
composite = [True] * 2 + [False] * n
for p in xrange(n + 1):
if composite[p]:
continue
q = p
m = 1
total_prime_power = 0
prime_power = [0] * (n + 1)
while True:
prime_power[q] = prime_power[m] + 1
r = q
if q <= k:
total_prime_power -= prime_power[q]
if q > n - k:
total_prime_power += prime_power[q]
m += 1
q += p
if q > n:
break
composite[q] = True
prime_factors.append([p, total_prime_power])
print prime_factors
Recursive function is used incorrectly here. fact() function should be changed into this:
int fact(int n){
if(n==0||n==1) //factorial of both 0 and 1 is 1. Base case.
{
return 1;
}else
return (n*fact(n-1));//recursive call.
};
Recursive call should be made in else part.
NCR() function should be changed into this:
int NCR(int n,int r){
if(n==r) {
return 1;
} else if (r==0&&n!=0) {
return 1;
} else if(r==1)
{
return n;
}
else
{
return fact(n)/(fact(r)*fact(n-r));
}
};
// CPP program To calculate The Value Of nCr
#include <bits/stdc++.h>
using namespace std;
int fact(int n);
int nCr(int n, int r)
{
return fact(n) / (fact(r) * fact(n - r));
}
// Returns factorial of n
int fact(int n)
{
int res = 1;
for (int i = 2; i <= n; i++)
res = res * i;
return res;
}
// Driver code
int main()
{
int n = 5, r = 3;
cout << nCr(n, r);
return 0;
}
I made up my mind to write a little piece of code that gets two integers, lets say M and N ( M <= N ) and sum the digits of all the integers between them, inclusive. So for example if M = 1 and N = 9, DigitSum will equal to 45. If M = 10 and N = 11 the sum will be (1 + 0 (10) + 1 + 1 (11) = 3).
Here is my code so far (Done the for loop instead of the return):
#include <iostream>
#include <vector>
using namespace std;
// the partial digits sums digitSum[i] = the sum of the digits between 0 and i
int digitSum[] = {0, 1, 3, 6, 10, 15, 21, 28, 36, 45};
int pow_of_ten[] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};
// the sums of all the digits in the numbers from 1 to (10^(i) - 1) where i is the index in the array
long subsums[] = {0, 45, 20 * 45, 300 * 45, 4000 * 45, 50000 * 45, 600000 * 45, 7000000 * 45, 80000000 * 45,
900000000 * 45};
//Calculates the sum of all digits between 0 and M inclusive
long Digit_Sum(int M) {
if (M < 10) {
return digitSum[M];
}
long result = 0;
int same = M;
int counter = 0;
int lastdigit = 0;
while (same > 0) {
if (same < 10) {
lastdigit = same;
break;
}
same /= 10;
counter ++;
}
for(;counter >= 0; counter --) {
result += (subsums[counter] + M % pow_of_ten[counter] + 1) * lastdigit;
result += digitSum[lastdigit - 1] * pow_of_ten[counter];
if (counter == 0) {
break;
}
lastdigit = (M / pow_of_ten[counter - 1]) % 10;
}
return result;
}
int main() {
int M;
int N;
vector<long> sums;
while (true) {
cin >> M >> N;
if (M == 0 && N == 0) {
break;
}
sums.push_back(Digit_Sum(N) - Digit_Sum(M - 1));
}
for (vector<long>::iterator it = sums.begin(); it != sums.end(); ++it) {
cout << *it << endl;
}
}
For most cases this works well but an Online judge says it is wrong. I looked at other solutions that work but no one hard-coded the values in arrays the way I did. May this cause a partial problem, any ideas?
You can easily just create a for-loop to greatly simplify this code.
There is no need to go through all that effort.
for (Initialization Action, Boolean Expression, Update_Action)
Re deletion below: sorry, I have a bit influenza and mizread N as M. :(
I think a main error is M-1 in
sums.push_back(Digit_Sum(N) - Digit_Sum(M - 1));
Also noting that <when corrected that formula will only work for single-digit numbers. My comment earlier about using a simple formula was based on misunderstanding your problem description, in view of that formula and your examples. Both indicated single digit numbers only.
However, the complexity of the code appears unreasonably high. Consider this, assuming non-negative integers as input, and assuming m is always less than or equal to n:
#include <iostream>
#include <stdexcept>
using namespace std;
bool throwX() { throw std::runtime_error( "Ouch." ); }
auto main() -> int
{
for( ;; )
{
int m, n;
cin >> m >> n || throwX();
if( m == 0 && n == 0 ) { break; }
int sum = 0;
for( int i = m; i <= n; ++i )
{
for( int v = i; v != 0; v /= 10 )
{
sum += v % 10;
}
}
cout << sum << endl;
}
}
It needs not be more complicated than that.
Tested and working to spec, sans console input:
#include <iostream>
#include <string>
using namespace std;
void sum_a_to_b(const int & a, const int & b)
{
if (a <= b && a >= 0)
{
long long sum = 0;
for (int i = a; i <= b; i++)
{
sum += i;
}
cout << "Sum of digits from " << a << " through " << b << " is " << sum << ".\n";
}
}
int main()
{
sum_a_to_b(5, 6);
sum_a_to_b(1, 9);
}
I have an integer positive number n. Let's say n=5 for example. If we look at multiplies of n, we see these numbers (let's call it n-grid) [... -15, -10, -5, 0, 5, 10, 15, ...]. Now I need to write a function F(n, N) that, given an integer N, outputs a closest number from that n-grid. For instance, F(n, 0) = 0 (for any n). F(5, 4) = 5, F(5, 7) = 5, F(5, 8) = 10, F(5, -13) = -15 and so on.
I've written this function:
int const x = ((::abs(N) + (n / 2)) / n) * n;
if (N > 0)
{
return x;
}
else
{
return -x;
}
It seems to work but don't like how it looks. Can anybody suggest any improvement?
You could possibly get rid of the if statement by multiplying x by (N/abs(N)) and returning the calculated value immeadiatelly, without even saving it in x.
I would not do this however, because it would harm readability.
This might be simple to understand and to look even,
int grid(int n, int N){
if (N == 0) return N;
return n * (N > 0 ? (n + N)/n : (n + abs(N))/n );
}
Here is the ideone result.
int closest_number(int n,int N)
{
if(N==0)
return N;
else if(N > 0)
{
int temp = N % n;
if(temp > (n/2))
return (n*((N/n)+1));
else
return (n*(N/n));
}
else
{
int temp = N % n;
if(abs(temp) > (n/2))
return (n*((N/n)-1));
else
return (n*(N/n));
}
}
You can find the ideone output for the given set of test cases here http://ideone.com/NlJiPt
here is simple math solution :-
F(k,x) = (x/k)*k if abs(x-(x/k)*k) <= k/2
= (x/k)*k + sign(x)*k otherwise
C Implementation :-
#include<stdio.h>
#include<math.h>
int func(int k,int x) {
int a = (x/k)*k;
int sign = x/abs(x);
if(abs(x-a)<=k/2)
return(a);
else return(a+sign*k);
}
int main() {
printf("%d",func(5,121));
return 0;
}
You are describing a rounding algorithm; you need to specify whether rounding is symmetric or not, and then whether it is up or down (or toward/away from zero for symmetric). ideone demo for below code.
// F(4, 6) F(4, -6)
int symmetricTowardZero(int n, int N) {
return n * (int)(N / n); // 4 -4
}
int symmetricAwayFromZero(int n, int N) {
return n * (int)(N / n + (N < 0 ? -0.5 : +0.5)); // 8 -8
}
int unsymmetricDownward(int n, int N) {
return n * floor((double)N / n); // 4 -8
}
int unsymmetricUpward(int n, int N) {
return n * ceil((double)N / n); // 8 -4
}