zoukankan      html  css  js  c++  java
  • Trailing Zeroes

    题目:

    Trailing Zeroes 

    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

    题解:

    解法一:

    这是一个二分经典题,主要思路为定义一个求n!后面0的数量的函数,然后二分。为什么要二分呢,因为你用朴素算法方法求的话,每次都要循环1e8次,肯定会TL,用二分查找可以快很多。

    (二分搜索,在有序序列查找值上非常方便。通过一次比较,可以把解的范围缩小一半。反复与区间的重点进行比较,就可以不断把解的范围缩小到原来的一半,最终在O(logn)次的比较之内求得最终的解。)

    求n!后面0的数量请参考我的CSDN博客中的一篇文章:https://blog.csdn.net/qq_45328552/article/details/98206579

    我会在代码里分析一下二分。

    #include <iostream>
    
    using namespace std;
    
    typedef long long ll;
    
    int search(ll n)
    {
        int sum = 0;
        
        while(n)
        {
            sum += n/5;
            n /= 5;
        }
        
        return sum;
    }
    
    int main()
    {
    //    freopen("input.txt","r",stdin);    //注释!注释!!! 
        
        int t, n;
        
        cin >> t;
        
        for(int i = 1; i <= t; i ++ )
        {
            cin >> n;
            
            ll head = 0, tail = 5e8 + 5, mid; 
            //定义二分的头和尾及mid,注意定义成long long类型,因为二分一般都是求非常大的数 
            while(head <= tail) //二分循环需要满足的条件,头小于尾 
            {
                mid = (head + tail) / 2;  
                
                if(search(mid) < n) head = mid + 1; //search(mid)小于n,则所求值必在右边,mid以及mid左边的数都不满足,因此让头等于mid+1 
                else if(search(mid) > n) tail = mid - 1; //search(mid)大于n,所求值必在左边,mid及mid右边的数都不满足,因此让尾等于mid-1 
                else break; //等于则跳出循环,因为已经确定了要找的值 
            }
            
            if(head > tail) printf("Case %d: impossible
    ", i); //head > tail找到不满足条件还找不到,说明已经完全二分还找不到符合条件的数,输出false 
            else printf("Case %d: %d
    ", i, mid - mid % 5);    //根据上面的代码可以知道这是search(mid)=n符合条件的值,输出即可 
        }    //输出mid-mid%5的原因是阶乘后面0的数量相同的数会有重复的而这里要求满足条件的最小值6、7、8和5的阶乘后面0的数量是相同的,6、7、8减去6、7、8 % 5后就变成满足条件的最小值了                        
        return 0;
    }

     解法二:

    我同学用了打表的方法做出了这道题,也是很强了。打表的时候看着数据4、5一组很慢、很慢地通过,最后成功AC,真的很爽。

    打表注意事项:1、明白阶乘为0的数量的最小数为5的倍数,从而以5为倍数进行循环。

    2、提前打好表,使用标记数组的思维去打表。不要在循环体内一次一次地去打表,肯定TL;

    #pragma GCC optimize(2)
    #include <bits/stdc++.h> 
    using namespace std;
    
    typedef long long ll;
    const int N=1e8+10;
    
    int f[N];
    
    int search(int n)
    {
        int num = 0;
        while(n)
        {
            num+=n/5;
            n/=5;
        }
        return num;
     } 
    
    int main()
    {
    //    freopen("input.txt", "r", stdin);
        //提交时注释,调试时取消注释!!! 
        int t;
        cin >> t;
        for(int i=5;i<1e8+10;i+=5)
        {
            f[search(i)]=i;
        }
        int tmp;
        for(int i=0;i<t;i++)
        {
            scanf("%d",&tmp);
            if(f[tmp]!=0) printf("%d
    ",f[tmp]);
            else printf("impossible
    ");
        }        
        return 0;
    }

    皓齿蛾眉,命曰伐性之斧。 --《吕氏春秋 》

    http://www.dxswb.com/shijian/219063.html
  • 相关阅读:
    搜索回车跳转页面
    登录验证码
    【排序算法】排序算法之插入排序
    PAT 乙级 1044 火星数字 (20 分)
    PAT 甲级 1035 Password (20 分)
    PAT 甲级 1041 Be Unique (20 分)
    PAT 甲级 1054 The Dominant Color (20 分)
    PAT 甲级 1027 Colors in Mars (20 分)
    PAT 甲级 1083 List Grades (25 分)
    PAT 甲级 1005 Spell It Right (20 分)
  • 原文地址:https://www.cnblogs.com/pioneer1/p/11290936.html
Copyright © 2011-2022 走看看