杭电 ACM题老师出错!

开学了,杭电又迎来了好多新生。ACMer想为新生准备一个节目。来报名要表演节目的人很多,多达N个,但是只需要从这N个人中选M个就够了,一共有多少种选择方法?
Input
数据的第一行包括一个正整数T,接下来有T组数据,每组数据占一行。
每组数据包含两个整数N(来报名的人数,1<=N<=30),M(节目需要的人数0<=M<=30)

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

我的程序!

#include<stdio.h>
int main()
{

long x,y,s,t,n,m,i;
scanf("%ld",&t);
while(t--)
{
scanf("%ld%ld",&n,&m);
if(n<m)
{ s=0;
printf("%ld\n",s);

}
else if(m==0)
{
s=1;
printf("%ld\n",s);

}
else
{
x=1;
for(i=n;i>=n-m+1;i--)
x=x*i;
y=1;
for(i=1;i<=m;i++)
y=y*i;
s=x/y;
printf("%ld\n",s);
}
}
return 0;
}
不知道,什么地方错了!
这道题用你的代码 如果n=20 m=15
你看看输出多少?
是0
为什么
原因有点多
long的范围不够大
你先求x的阶乘那里就溢出了 然后s=x/y 结果取整数是0
避免溢出的方法可以清销这样:
x,y用双精度浮点数表示 乘一个x立即除以一个y
最后对s四舍五入输出
看代码:
#include <stdio.h>消正唯
double sq(int *_point1,int *_point2);
void main()
{
int t;
int n,m;
int *p1,*p2;
p1=&n; p2=&m;
scanf("%d",&t);
while (t>0)
{
t--;
scanf("%d%d",p1,p2);
if (*p1<*p2) printf("0\n");
else printf("%.lf\n"拿培,sq(p1,p2));
}
}

double sq(int *_point1,int *_point2)
{
int i,j;
double s=1;
if (*_point2>*_point1/2) *_point2=*_point1-*_point2;
for(i=*_point2,j=*_point1;i>=1;i--,j--)
s*=j/(i*1.0);
return s;
}
所有ACM程序都应该是一个无限循环,
最好的办法蠢埋芦液裂是这带带么写
while(scanf()!=EOF) //scanf里是你要输入的第一个值