It is a very simple program which have t test cases, and we have to find nCr=n!/r!*(n-r)!. So it works fine for smaller values like 20C2 but not for larger values lke 100C10. It gives 32C2=-6 ,100C10 floating point exception. how to make it for 1<=n<=r<=1000 ?? NOTE: I am not asking for long double or don't want to change it into float.Answer should be like 100C10 = 17310309456440 similarly 989C45=?
#include<iostream>
using namespace std;
long long int fact(long long int num);
int main()
{
int t;
cin>>t;
long long int n[1000],r[1000],c[1000];
for(int i=0;i<t;i++)
{
cin>>n[i];
cin>>r[i];
}
for(int i=0;i<t;i++)
{
c[i]=fact(n[i])/(fact(r[i])*fact(n[i]-r[i])) ;
cout<<c[i];
}
return 0;
}
long long int fact(long long int num){
long long int k;
if(num==0)
num=1;
else
{
for(k=num-1;k>0;k--)
num=num*k;
}
return num;
}
Time for a touch of Maths:
An example makes this easier, let's do 5C3:
So we can see that some of the factors will cancel; that is very useful if the full
fact(n)
would overflow.Define a range factorial:
Then
We could stop here, and we would have significantly broadened the set of values of
n
andr
for which we can calculate values without overflowing.Extra points
With
rafa(n,r)
andfact(r)
, we can see that whenr
is nearly as large asn
, then most of the scale of the problem will cancel. So 100C97 = 100x99x98 / 3x2x1 = 100x33x49.Consider, then, a factor-matching algorithm (psuedo-code rather like python):
You can then perform the final calculation of the product of the numerator elements divided by the product of the remaining denominator elements. Since we know nCr always returns an integer result, we know that when cancelFactors is used it will always cancel all the factors. Thus this algorithm maximises the possible space of n,r pairs which do not overflow. However, as written, it is O(n^3 * f), where
f
is the cost of getting all the factors of an integer, so it will not be fast. For large values of n and r, though, it may be the only way to calculate the result without using different types.