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