Problem C: 勤劳的ACgirls
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 68 Solved: 22
[ Submit][ Status][ Web Board]
Description
zjc的ACgirls队的队员最近比较忙,为了能够取得更好的比赛成绩,他们制定了一个m天a掉n题的计划,a掉一题可以是这m天的任何时候。
为了表示对acmer事业的热爱,队长wc要求每天必须至少要ac掉k题,这m天每天ac掉的题数可以用一个m元组表示。
设不同的m元组一共有c个,请问c的末尾有多少个0?(如果c是0,输出0)
为了表示对acmer事业的热爱,队长wc要求每天必须至少要ac掉k题,这m天每天ac掉的题数可以用一个m元组表示。
设不同的m元组一共有c个,请问c的末尾有多少个0?(如果c是0,输出0)
Input
多组测试数据,处理到文件结束。(测试例数量<=160000)
输入的每一行是一个测试例,分别是m、n和k(0<=m,n,k<=1e9),含义如前所述。
Output
每组测试例中
m元组的数量的末尾
0的个数,占一行。
Sample Input
3 11 0
3 11 1
999 99999 4
Sample Output
0
0
5
题解:简单的想就是n个相同球放到m个不同的盒子里。
知识点:
1. n个相同的球放入m个不同的盒子:
a. 不允许盒子为空: C(n-1,m-1)
b. 允许盒子为空: C(n+m-1,m-1) 假设存在n+m-1个球,然后隔板
2. n个相同的球放入m个相同的盒子,可看成将正整数n划分成m组:
a. 不允许盒子为空,分为最小一组元素个数为1和最小一组元素个数为2的两种情况: 那么S(n,m) = S(n-1,m) + S(n-m,m),S(i,1) = 1, S(n-m,k) = 0 (若n-m < 0)
b. 允许盒子为空,可以每盒先放一个,这样成为不允许盒子为空,n+m个相同的球放入m个相同的盒子的个数。
3. n个不同的球放入m个不同的盒子
a. 不允许为空,m!*S(n,m),S(n,m)为第二类斯特林数
b. 允许为空m^n
4. n个不同的球放入m个相同的盒子
a. 不允许为空,例如S(4,2) = 7,还是分为最小一组元素个数为1和最小一组元素个数为2两种情况:那么S(n,m) = m*S(n-1,m) + S(n-1, m-1),这就是第二类斯特林数的递推公式。
b. 允许为空,把上面的都加起来R(n,m) = S(n,1)+S(n,2)+...+S(n,m)
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
ll solve5(ll a){ll sum=0;while(a){sum+=a/5;a/=5;}return sum;}
ll solve2(ll a){ll sum=0;while(a){sum+=a/2;a/=2;}return sum;}
int main()
{
ll n,m,k;
while(scanf("%lld%lld%lld",&m,&n,&k)!=EOF)
{
if(m*k>n){printf("0\n");continue;}n-=m*k;
ll a=n+m-1,b=n,c=a-b;
ll a2,b2,c2,a1,b1,c1;
a1=solve2(a);a2=solve5(a);
b1=solve2(b);b2=solve5(b);
c1=solve2(c);c2=solve5(c);
ll ans1=a1-b1-c1;ll ans2=a2-b2-c2;
printf("%lld\n",max(0ll,min(ans1,ans2)));
}
return 0;
}