题目链接:
LightOJ 1138 Trailing Zeroes (III)
题意:
求最小的自然数n使得n的阶乘结果以Q个0结尾。如果不存在这样的数输出impossible。
1<= Q <= 1e8.
分析:
首先如果存在解的话,n一定是5的倍数。
5的阶乘后面有1个0;
10的阶乘后面有2个0;
15的阶乘后面有3个0;
20的阶乘后面有4个0;
25的阶乘后面有6个0.。
所以对于一个自然数x,它的阶乘结果后面0的个数num = x / 5 + x / 25 + x / 125 + x / 625 + …。
而且对于任意的x’(x’ > x) 它的阶乘结果后面的0的个数num’ >= num。所以可以二分答案解决了!
最后再检验下二分出来的答案是否正好num == Q即可。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <climits>
#include <cmath>
#include <ctime>
#include <cassert>
#define IOS ios_base::sync_with_stdio(0); cin.tie(0);
using namespace std;
typedef long long ll;int T, len, cases = 0;
ll Q, base[20];inline ll check(ll x)
{ll res = 0;for(int i = 0; i < len; i++){res += x / base[i];}return res;
}void init()
{base[0] = 5, len = 13;for(int i = 1; i < len; i++){base[i] = base[i - 1] * 5;}
}int main()
{init();scanf("%d", &T);while(T--){scanf("%lld", &Q);ll high = base[len - 1], low = 0;while( high > low){ll mid = (high + low) / 2;if(check(mid) >= Q) high = mid;else low = mid + 1;}printf("Case %d: ", ++cases);if(check(high) == Q) printf("%lld\n", high);else printf("impossible\n");}return 0;
}