QHUOJ - 1533: 计算组合数(大数计算)
题目描述
给定两个正整数n,m,计算组合数C(n,m)。组合数计算公式为:C(n,m)=n!/((n-m)!*m!)
已知n,m <= 50. 结果很大需要使用long long存储。
输入
输入两个整数n,m
输出
输出结果
样例输入
4 2
样例输出
6
题目中,运算的结果可以在long long的类型中存储,但是运算过程中产生的数据是存不下的,所以进行了拆分运算。
例如:50!,把50*49*...*41的结果存在一个long long的类型中(这个结果能不能存下没有验证,在这只是说明方法),40*39*...*31的结果再存到一个long long的类型中。
大概就是这个意思,分开来进行运算。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int main() { int n,m; scanf("%d %d",&n,&m); long long sum=1; long long a[5]={1,1,1,1,1}; int b[50]; int num=0; int ans=0; for(int k=0,i = n;i>n-m;i--) { if(k==5) //每5个数为一组,把运算结果存到a数组中。 { ans++; k = 0; } a[ans] = a[ans]*i; k++; } ans = 0; for(int k=0,i = m;i>1;i--) //分开进行除法运算, { if(k==5) { ans++; k = 0; } if(a[ans]%i == 0) { a[ans] = a[ans]/i; k++; } else { b[num] = i; num++; } } for(int i = 0;i<5;i++) //对于上一部分中不能整除的数,看其可否被a数组中的其他数整除 { for(int j = 0;j<num;j++) { if(a[i]%b[j] == 0 && b[j] != 1) { a[i] = a[i]/b[j]; b[j] = 1; } } } for(int i = 0;i<5;i++) //求结果 { sum = sum * a[i]; } printf("%lld\n",sum); return 0; }