Find the number of trailing zeroes for the following function:
C(n, r)*p^q
where n, r, p, q are given as Input.
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 ≤ 10^6, r ≤ n).
Output
For each test case, print the case number and the number of trailing zeroes.
Sample
Input | Output |
---|---|
2 10 4 1 1 100 5 40 5 | Case 1: 1 Case 2: 6 |
Note
For case 1, n = 10, r = 4, p = 1, q = 1, then the result is 210 and number of trailing zeroes is 1.
题意: 求C(n, r)*p^q有多少个末尾的0。
分析: 考虑最终结果的质因式分解,如果有多少组成对的5和2就有多少个0,所以问题就是求这个式子有多少个因数是5和2。对于p^q就很好处理,直接p质因数分解,然后分别乘上q,对于前面的组合数需要转换为阶乘,对于一个阶乘求某个数字作为因数出现次数是比较容易的,从全局考虑,先求5^1出现次数,再加5^2出现次数,依此类推直到5^k出现次数为0。对于组合数式子就是分子上的阶乘用加法,分母上的阶乘用减法。
具体代码如下:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <string>
using namespace std;
//需要知道n!中5作为因数出现个数怎么求
//分别求5^1、5^2、5^3......出现次数,然后加和
signed main()
{
int T;
cin >> T;
for(int i = 1; i <= T; i++)
{
int n, r, p, q;
scanf("%d%d%d%d", &n, &r, &p, &q);
printf("Case %d: ", i);
int num2, num5;
num2 = num5 = 0;
int t = p;
while(t%5 == 0) t /= 5, num5++;
while(t%2 == 0) t /= 2, num2++;
num5 *= q, num2 *= q;
t = n;
while(t) num5 += t/5, t /= 5;
t = n;
while(t) num2 += t/2, t /= 2;
t = n-r;
while(t) num5 -= t/5, t /= 5;
t = n-r;
while(t) num2 -= t/2, t /= 2;
t = r;
while(t) num5 -= t/5, t /= 5;
t = r;
while(t) num2 -= t/2, t /= 2;
printf("%d\n", min(num2, num5));
}
return 0;
}