C++简单题,跪求高手指错

来源:百度知道 编辑:UC知道 时间:2024/06/18 03:37:27
开学了,杭电又迎来了好多新生。ACMer想为新生准备一个节目。来报名要表演节目的人很多,多达N个,但是只需要从这N个人中选M个就够了,一共有多少种选择方法?

Input
数据的第一行包括一个正整数T,接下来有T组数据,每组数据占一行。
每组数据包含两个整数N(来报名的人数,1<=N<=30),M(节目需要的人数0<=M<=30)

Output
每组数据输出一个整数,每个输出占一行

Sample Input

5
3 2
5 3
4 4
3 6
8 0

Sample Output

3
10
1
0
1

#include<iostream>
using namespace std;
int main()
{
int n,m,t,x,i,y;
cin>>t;
while(t--)
{
cin>>n>>m;
x=y=1;
if(m==0)
{cout<<'1'<<endl;continue;}
if(n<m)
{cout<<'0'<<endl;continue;}
for(i=n;i>n-m;i--)
x*=i;
for(i=m;i>0;i--)
y*=i;
cout<<x/y<<endl;
}
return 0;
}
仅用示例验证完全正确,可是提交到OJ上

30!很大超出了表示范围
我这里有个模板,用加法求组合数,可以解决溢出

#include <cstdio>

int cal(int n, int m)
{
int i, a, b, p;
if(n<m){i=m;m=n;n=i;}
p=1;
a=n-m<m?n-m:m;
b=n-m>m?n-m:m;
for(i=1; i<=a; i++)
p+=p*b/i;
return p;
}

int main()
{
int n,m;
while(1)
{
scanf("%d%d",&n,&m);
printf("%d\n",cal(n,m));
}
}

中间步骤溢出了,x会溢出。