Trailing Zeroes (III)?点击打开题目
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
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.
Output
For each case, print the case number and N. If no solution is found then print 'impossible'.
Sample Input
3
1
2
5
Sample Output
Case 1: 5
Case 2: 10
Case 3: impossible
刚开始拿到这个题目的时候就在想,是不是要不所有的可能的书又看一遍,然后找到符合条件的书,如果找得到,就输出答案,否则输出impossible,但是发现那样真的是太慢了,我自己跑的时候都要好长时间,然后听好了同学说用二分,然后而很多额head和tail在最后也老是搞不清楚,于是胡乱写了些,其实也能跑正确答案来着,
分析,说是找0,无非就是找2和5的个数,但是一个数的阶乘的话,肯定是5的数目比2的数目少,(各个数中因子中2和5的个数),其实这个条件很好写的,随便找个数来看
后来在学离散数学的时候在课后有过这么一个题,是计算n=1000的阶乘,其实就是i从5开始取5的指数次幂,并且i<=n;然后依次将n/i累加,就是n内5个数了,然后再进行优化一下其实就是n一直整除5,然后将商累加即
while(n)
{
ans+=(n/5);//ans即为每次商的累加
n/=5;
}
比如在39之内有多少个5,其实就是39/5+39/25=8个
5,10,15,20,25(2个),30,35
然后就是二分的过程,二分比较好写
#include<iostream>
using namespace std;
const int maxw=5e8;
int search(int n)//找出n中5的个数
{
int ans=0;
while(n)
{
ans+=(n/5);//ans为商的累加,即5的个数
n/=5;
}
return ans;
}
int main()
{
int t,n;
cin>>t;
for(int i=1;i<=t;i++)
{
cin>>n;
int head=4,tail=maxw,mid,num;
while(head<=tail)
{
mid=(head+tail)/2;
num=search(mid);
if(num<n)
head=mid+1;
else
tail=mid-1;
}
num=search(head);
if(num==n)
cout<<"Case "<<i<<": "<<head<<endl;
else
cout<<"Case "<<i<<": impossible"<<endl;
}
return 0;
}