Factorial

6 篇文章 0 订阅
6 篇文章 0 订阅
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

One number Q written in the input (0<=Q<=10^8).

Output

Write "No solution", if there is no such number N, and N otherwise.

Sample Input


Sample test(s)

Input
2

Output
10

解题报告:
原来做过这样一个题,求n!末尾有几个0,先要把这个题搞懂。在n!要把每个数拆分成质因数的积,N!=2^a*3^b*5^c*7^d........因为只有2*5 才会出现 0,所以质因数有多少5,尾部就有多少个0,且2的个数会比5多很多,所以只要求5的个数即可。有一个公式:
设f(n)为n!末尾0的个数,则
         0(0<n<5)
f(n!)=
         k+f(k!)(k=n/5)
有了这个公式之后,关键代码就为:
while(n)
{
n/=5;
i+=n;
}
最后输出i的值即可。
同样,这个题

Q = N/5 + N/(5^2) + N/(5^3) + ...

由等比数列求和可得(设只到前k项):

Q = N(5^k - 1) / [4*(5^k)],由此得:

N = 4Q * [(5^k)/(5^k-1)]

注意:当Q为0时要输出1

#include <cstdio>
#include <cstring>
using namespace std;
 
int fun(int x) {    //求x尾部有多少个0 
    int sum = 0;
    while(x) {
        sum += x / 5;
        x /= 5;
    }
    return sum;
}
 
int main() {
    int Q;
    while(scanf("%d", &Q) != EOF) {
        if(Q == 0) {
            printf("1\n");
            continue;
        }
         
        int N = Q * 4 / 5 * 5;      //依据公式先大致算到4*Q(除5乘5是为了N正好是5的倍数),然后再往后推 
        while(fun(N) < Q) {
            N += 5;
        }
         
        if(fun(N) == Q) printf("%d\n", N);
        else printf("No solution\n");
    }
    return 0;
}


这个题也可以用二分算:


#include<iostream>  
#include<string.h>  
#include<stdio.h>  
#include<ctype.h>  
#include<algorithm>  
#include<stack>  
#include<queue>  
#include<set>  
#include<math.h>  
#include<vector>  
#include<map>  
#include<deque>  
#include<list>  
#define N 0x7fffffff  
using namespace std;  
int num0(int n)  
{  
    int count=0;  
    while(n)  
    {  
        count+=n/5;  
        n/=5;  
    }  
    return count;  
}  
void find(int w)  
{  
    int left=0,right=N,mid;  
    while(left<=right)  
    {  
        mid=(left+right)>>1;//位运算速度快  
//        mid=(left+right)/2;  
        if(num0(mid)>=w)  
        right=mid-1;  
        else  
        left=mid+1;  
    }  
    if(num0(left)==w)  
    printf("%d\n",left);  
    else  
    puts("No solution");  
}  
int main()  
{  
    int n;  
    while(scanf("%d",&n)!=EOF)  
    {  
        if(n==0)  
        printf("1\n");  
        else  
        {  
            find(n);  
        }  
    }  
    return 0;  
}  



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值