lightoj 1138

来源:互联网 发布:知る是几段动词 编辑:程序博客网 时间:2024/06/06 20:17

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

Output for Sample Input

3

1

2

5

Case 1: 5

Case 2: 10

Case 3: impossible



题意:给你一个n,问你多少的阶层后面有n个零。

要算一个阶层后面有多少个零,可以把每一个数看成是质因子幂的乘积,那么只要找出有多少对2和5,就能算出有多少个0。

对于一个阶层,里面不是5的倍数的数不做贡献,所以比如29的阶层就可以看成 5 X 10 X 15 X 20 X 25,是5的一次方的整倍数的数有一个5因子,是5的二次方的整倍数的数有两个5因子,以此类推。

这样就能算出任意一个给定n的阶层中0的数量,而且n越大,0的数量越多,是单调的,那么每次二分找答案就可以了。

#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#define LL long longusing namespace std;int n;int cont(int x){    int cnt = 0;    while(x)    {        cnt += x/5;        x /= 5;    }    return cnt;}/*这样写更容易看明白一点int cont(int x){    int cnt = 0;    int t = 5;    while(x/t)    {        cnt += x/t;        t *= 5;    }    return cnt;}*/int binarysearch(){    int l = 1,r = 1e9;    int ans = r;    while(l <= r)    {        int mid = (l+r)/2;        if(cont(mid) >= n)        {            ans = mid;            r = mid - 1;        }        else            l = mid + 1;    }    return ans;}int main(void){    int T,i,j;    scanf("%d",&T);    int cas = 1;    while(T--)    {        scanf("%d",&n);        int ans = binarysearch();        if(cont(ans) != n)            printf("Case %d: impossible\n",cas++);        else            printf("Case %d: %d\n",cas++,ans);    }    return 0;}