Trailing Zeroes (II)

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一般都是把这个数进行因子分解求2的个数与5的个数,然后较小的就是这个数末尾0的个数,因为本题要求的数是除法的形式,因为的分子上的2与5是可以和分母上的2与5抵消的,所以求2的个数就是分子上2的个数减去分母上2的个数,求5的个数就是分子上5的个数减去分母上5的个数,然后找到一个较小的即为结果,因为此题数据范围较大,所以先打一个表,要用到前缀和二维数组num【】【】,num【i】【0】数组来存储 从1到 i 中因子2的总个数,num【i】【1】数组来存储从1到 i 中因子5的总个数。最后进行处理就得到结果啦,代码如下:

#include<stdio.h>
#include<string>
#include<queue>
#include<math.h>
#define inf 0x3f3f3f3f
#define LL long long
#include<string.h>
#include<algorithm>
using namespace std;
int num[1000010][2]= {0};
void init()
{
    num[1][0]=0;
    num[1][1]=0;
    for(int i=2; i<1000010; i++)
    {
        int x=i;
        num[i][0]=num[i-1][0];
        while(x%2==0)
        {
            num[i][0]++;
            x=x/2;
        }
        int x1=i;
        num[i][1]=num[i-1][1];
        while(x1%5==0)
        {
            num[i][1]++;
            x1=x1/5;
        }
    }
}
int main()
{
    int T,cas=1;
    init();
    int n,r,p,q;
    scanf("%d",&T);
    while(T--)
    {
        int s2,s5;
        scanf("%d %d %d %d",&n,&r,&p,&q);
        s2=num[n][0]-num[r][0]-num[n-r][0]+(num[p][0]-num[p-1][0])*q;
        s5=num[n][1]-num[r][1]-num[n-r][1]+(num[p][1]-num[p-1][1])*q;
        printf("Case %d: ",cas++);
        if(s2>s5)
            printf("%d\n",s5);
        else
            printf("%d\n",s2);
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值