Trailing Zeroes (II) (求末尾0的个数)

Find the number of trailing zeroes for the following function:

nCr * pq

where n, r, p, q are given. For example, if n = 10, r = 4, p = 1, q = 1, then the number is 210 so, number of trailing zeroes is 1.

Input

Input starts with an integer T (≤ 10000), denoting the number of test cases.

Each case contains four integers: n, r, p, q (1 ≤ n, r, p, q ≤ 106, r ≤ n).

Output

For each test case, print the case number and the number of trailing zeroes.

Sample Input

2

10 4 1 1

100 5 40 5

Sample Output

Case 1: 1

Case 2: 6

题意:求 组合数C(n,r) *  p^q 末尾0的个数。

思路:又是求末尾0的个数,末尾0就和 10 , 2 ,5有关,所以我们就可以用一个前缀和记录每一个数之前,10,5,2出现的次数。对于组合数 C(n,r) = n! / r ! * (n-r) !   emmm....好像知道这么多就够了吧。

代码如下:

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define N 1000010
using namespace std;
int num10[N],num5[N],num2[N];
void init()  //打表,算前缀和
{
    for(int i=1; i<N; i++)
    {
        int x=i;
        while(x%10==0) //这个数含有多少个10,下面同理,
        {
            x/=10;
            num10[i]++;
        }
        while(x%5==0)
        {
            x/=5;
            num5[i]++;
        }
        while(x%2==0)
        {
            x/=2;
            num2[i]++;
        }
        num10[i]+=num10[i-1]; //算前缀和
        num5[i]+=num5[i-1];
        num2[i]+=num2[i-1];
    }
}
int solve(int n,int r,int p,int q)
{
    int a10=num10[n]-num10[r]-num10[n-r];//组合数含有10,5,2的个数
    int a5=num5[n]-num5[r]-num5[n-r];
    int a2=num2[n]-num2[r]-num2[n-r];   
    
    a10+=q*(num10[p]-num10[p-1]); //p^q次幂含有的10,5,2的个数
    a5+=q*(num5[p]-num5[p-1]);
    a2+=q*(num2[p]-num2[p-1]);
    return a10+min(a2,a5);//10的个数 + min(2,5的个数)
}
int main()
{
    init();
    int t,cas=1;
    scanf("%d",&t);
    while(t--)
    {
        int n,r,p,q;
        scanf("%d%d%d%d",&n,&r,&p,&q);
        printf("Case %d: %d\n",cas++,solve(n,r,p,q));
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值