题目:http://www.lightoj.com/volume_showproblem.php?problem=1138
题意:找到一个最小的数n,使n!末尾0的个数等于要求的个数,找不到输出impossible
思路:因为2 * 5 = 10,可以发现,某个数n阶乘末尾0的个数等于从1到n内所有数字含有因子5的个数,因此二分枚举n,求含有因子5的个数,找到一个最接近题目要求的n,向下减成5的倍数,然后判断是不是满足题目要求
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
int cas;
ll work(ll m)//从1到m内所有数字含有因子5的个数
{
ll tmp = 0;
while(m != 0) m /= 5, tmp += m;
return tmp;
}
int main()
{
int t;
ll n, sum;
scanf("%d", &t);
while(t--)
{
scanf("%lld", &n);
ll l = 5, r = 5 * n, res;
while(l <= r)
{
ll mid = (l + r) / 2;
ll tmp = work(mid);
if(tmp >= n) r = mid - 1, res = mid;
else l = mid + 1;
}
while(res % 5 != 0) res--;
if(work(res) != n) printf("Case %d: impossible\n", ++cas);
else printf("Case %d: %lld\n", ++cas, res);
}
return 0;
}