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
#include
#include
#include
#define inf 0x3f3f3f3f
#define LL long long
#include
#include
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;
}

 

你可能感兴趣的:(Trailing Zeroes (II))