这一切都要从一只蝙蝠说起。 我叫灰灰,是一只蝙蝠。我和我的家族住在又深又暗的山洞里。 一天,我去找我的好朋友——穿山甲球球玩。到了他家,只见球球的爸爸妈妈边流泪边默默地收拾东西。我一问才知道,球球被一种叫人类的动物抓走了,我只好伤心地回家了。 第二天,我和兄弟姐妹们在山洞外玩儿。忽然我听到了一些奇怪的声音。哥哥急忙对我们说:“又是那些人类!我们快躲起来。”于是我们赶快回家找爸爸妈妈,可是已经来不及了。为了保护我们,爸爸妈妈也被人类抓住了。 我难过地问哥哥:“人类为什么要抓走我们的爸爸妈妈?” 哥哥伤心地说:“他们很快就会被人类吃掉了。” 我不明白为什么,记得爸爸妈妈告诉我,以前人们都把我们当成是吉祥的象征。可现在,他们为什么还要吃我们呢?我很生气,我恨人类! 后来,我听说那些我们亲人的人类,都得了一种叫做“新型冠状病毒”的肺炎。好的,故事到此结束。开学了,由于疫情原因,同学们只能在家上网课,而老师在上课的时候为了确认所有的学生都有在听课,所以每节课都要点名。但是由于时间限制,每次老师只会点一部分同学,请问老师一共会有多少种不同的点名方式呢?
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
long long cnm(int n, int m)
{
long long sum = 1;
int k = 1;
if (m > n / 2)
m = n - m;
for (int i = n - m + 1; i <= n; i++)
{
sum *= (long long)i;
while (k <= m && sum % k == 0)
{
sum /= (long long)k;
k++;
}
}
return sum;
}
#include<stdio.h>
int main()
{
long long t, sum, j, total, choose;
scanf("%lld", &t);
while (t--)
{
sum = 1;
scanf("%lld %lld", &total, &choose);
if (total >= choose)
{
printf("%lld\n",cnm(total,choose));
}
else
{
printf("0\n");
}
}
return 0;
}
上面的代码是后来通过优化才通过这道题的
下面给出我一开始写的代码
int fat(int n)
{
int i;
int sum=1;
for(i=1;i<=n;i++)
{
sum*=i;
}
return sum;
}
#include<stdio.h>
int main()
{
int t,sum,j,total,choose;
scanf("%d",&t);
while(t--)
{
sum=1;
scanf("%d %d",&total,&choose);
if(total>=choose)
{
for(j=total;j>total-choose;j--)
{
sum*=j;
}
printf("%d\n",sum/fat(choose));
}
else
{
printf("0\n");
}
}
return 0;
}
如果你使用这个代码去测试sample input的话
你会发现都是正常输出
然而你并没有办法通过这道题
为什么呢!!!
你试试输入30 15
你会发现输出的结果根本不是我们想要的
原因就是溢出了
我们必须立刻优化!!!
首先对于像30 29 这样的输入都无法正常输出
我们可以利用Cnm=Cn(n-m)这个公式
所以我加了一个if(m>n/2)语句
然后就是对于求15! 都会溢出我们不妨不要一次性求出15!而是一个一个去除
这样就没问题了
这道题真是花了我不少时间