2017年第0届浙江工业大学之江学院程序设计竞赛决赛 Problem C: 勤劳的ACgirls(n个相同球放到m个不同的盒子里。)

Problem C: 勤劳的ACgirls

Time Limit: 1 Sec   Memory Limit: 128 MB
Submit: 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)

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;
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值