zoukankan      html  css  js  c++  java
  • 求n得阶乘得最后一位非零数字

    如题,最后一位数好求,他只和最后一位相乘后的最后一位有关,唯一影响我们得是末尾0,而阶乘中末尾0来自于2和5,(10得话可以看成2 * 5),所以有这个思想我们可以筛选出1 * 2 * 3 * .... * n中包含2和5得个数

    如下:

    int get2(int n)
    {
        if(n == 0)return 0;
        return n / 2 + get2(n / 2);
    }
    int get5(int n)
    {
        if(n == 0)return 0;
        return n / 5 + get5(n / 5);
    }
    

    解释:

    对于1 2 3 4 5 6 7 8 9 ^ 25 26 27 28 29 30
    我要想找里面任何一个包含5得数字,一眼看去筛选出含有5得只有:5 10 15 20 25 30,但是有的含有两个5啊,那我就提出一个5,把他降一个形态,然后继续去寻找……
    30 /5 = 6 得到原型 6!,其余得均为无关数,不必去管
    继续筛选1 2 3 4 5 6,这个6得阶乘,是上面筛选完后产生得,可能还存在着得数,这些数将会递归进行二次筛选

    这样我们完成了第一步,筛选完后,你会发现原来的阶乘

    1 2 3 4 5 6 7 8 9 ^ 25 26 27 28 29 30

    变成了

    1 1 3 1 1 3 7 1 9 1 11 3 13 7 3

    这样看反而有所不大直观,但是能够得出得就是最后剩下得就是1 3 7 9(尾数),1没有作用,而 3 7 9 结果观察,他们自身得n次方得位数有个周期

    1 3 9 7

    1 7 9 3

    1 9 1 9

    所以我们就可以取寻找原来那些数含有3,5,7得个数

    还是先看看原型

    1 2 3 4 5 6 7 8 9 ^ 25 26 27 28 29 30

    step 1对于这些数,我们要做得是奇偶分开

    1 3 5 7 9 。。。 2 4 6 8 10.。。。

    对于偶数唯一要做得就是抽2变型(递归step1)

    step2 对于奇数我们可以求取了,奇数中,每10个数中肯定含有1个3,7,9,所以返回得值中有n / 10然后对于非整得数,还要考虑其最后一位得大小选择性得+1 即+(n % 10 >= x)

    然后奇数中还有5,这个根据我们得拆分,是不应该纯在得所以递归 step 2(n/ 5 --- 抽5降形)

    为什么重复step2而不是step1呢?抽了5后不会出现偶数得情况吗??

    因为 奇偶分家得时候,进来的奇数已经不再是一个完整得阶乘了,但是对3 7 9 得寻找毫无影响,因为偶数都一眼找不出来,所以进来得5 是 5 15 25,降型后也是 1 3 5 .。。直接去应用step2

    到此就能够实现了

    int g(int n,int x)
    {
        if(n == 0)return 0;
        return n / 10 + (n % 10 >= x) + g(n / 5,x);
        //这里的5分解后只有奇数没有偶数ggm1,3,5,7....,然后再在奇数里筛选
        //因为10,20,这样的一开始再getx中是筛不进来得!!
    }
    int getx(int n,int x)//寻找这个数中
    {
        if(n == 0)return 0;
        return getx(n / 2,x) + g(n,x);
    }
    int numtable[4][4] ={
        6,2,4,8,
        1,3,9,7,//注意顺序得安排取0得时候代表有4个得时候得余数
        1,7,9,3,
        1,9,1,9
    };
    int main()
    {
        int n,m;
        while(~scanf("%d%d",&n,&m))
        {
            int num2 = get2(n) - get2(n-m);
            int num5 = get5(n) - get5(n-m);
            int num3 = getx(n,3) - getx(n-m,3);
            int num7 = getx(n,7) - getx(n-m,7);
            int num9 = getx(n,9) - getx(n-m,9);
            int res = 1;
            if(num5 > num2)
            {
                res = 5;
            }
            else if(num5 < num2)//WRONG 2 :只有不相等得时候才能乘法,因为numtable[0][0]也是有数据得肯定会造成影响
            {
                res *= numtable[0][(num2 - num5)%4];//WRONG 1 :乘上得是多余得2!!!
                res %= 10;
            }
            if(res != 5)
            {
                res *= numtable[1][num3%4];
                res %= 10;
                res *= numtable[2][num7%4];
                res %= 10;
                res *= numtable[3][num9%4];
                res %= 10;
            }
            printf("%d
    ",res);
        }
        return 0;
    }
    
  • 相关阅读:
    面向对象程序设计寒假作业3
    面向对象程序设计编程题完善1.0
    jq分片上传,可拖动上传
    给富文本框的头添加title
    vue的富文本编辑器使用,并且添加显示当前输入字数
    超出省略号
    关于缓存 windwo.localStorage和sessionStorage
    复制框里的内容
    同一标签添加多个背景图
    函数里添加超链接
  • 原文地址:https://www.cnblogs.com/DF-yimeng/p/8672333.html
Copyright © 2011-2022 走看看