Trailing Zeroes (III)LightOJ - 1138
You task is to find minimal natural number N, so that N! contains exactly Q zeroes on the trail in decimal notation. As you know N! = 1*2*...*N. For example, 5! = 120, 120 contains one zero on the trail.
Input starts with an integer T (≤ 10000), denoting the number of test cases.
Each case contains an integer Q (1 ≤ Q ≤ 108) in a line.
For each case, print the case number and N. If no solution is found then print 'impossible'.
3
1
2
5
Case 1: 5
Case 2: 10
Case 3: impossible
思路分析:(1)题意:给出一个整数q,看能否找出一个数据的阶乘的 末尾有q个0。
(2)思路:几个数相乘所得乘积末尾0的个数和这几个因数 中所含5的个数有关,即是由几个5相乘得到的。比如 呢,20中有一个5,25中有两个5,125中有三个5,所以 20*25*125中就有六个5相乘,末尾就会有6个0。
(3)看一个数n的阶乘末尾是否有q个0,也就是说看n中是 否含有q个5。要找到这样一个n可以采用二分的思想, 依次缩小查找的范围。左端点为1,右端点为无穷大 INF。
代码如下:
#include<cstdio>
#define INF 0x3f3f3f3f
typedef long long LL;
LL ling(LL x)
{
LL num=0;
while(x) //计算1~x中5的个数 ,即共有多少个5相乘,注意25是两个5相乘,125是三个5相乘
{
num+=x/5;
x/=5;
}
return num;
}
int main()
{
int t,k=0;
scanf("%d",&t);
while(t--)
{
LL q,ans;
scanf("%d",&q);
LL lb=1;
LL ub=INF;
while(ub>=lb) // 当ub<lb时结束循环
{
LL mid=(lb+ub)/2;
if(ling(mid)>=q) //说明所含0的个数大于等于q,要使查找的范围变小,更新右端点为mid-1,因为mid已经判断过了嘛
ub=mid-1;
else
lb=mid+1; //说明所含0的个数小于q,要使查找的范围变大,更新左端点为mid+1
}
if(ling(lb)==q) //判断区间左端点,因为当循环结束时ub<lb,此时的ub已经不满足条件,所以要带入lb进行判断哦
printf("Case %d: %lld\n",++k,lb);//最后要再判断一下,相等则存在,否则不存在
else
printf("Case %d: impossible\n",++k);
}
return 0;
}