• N的阶乘末尾有多少个零?


    创联ifLab的招新问答卷上看到这么一题

    核心问题是:

    求N!(N的阶乘)的末尾有多少个零?

    由于在N特别大的时候强行算出N!是不可能的,所以肯定要另找方法解决了。

    首先,为什么末尾会有0?因为2*5 = 10,0就这么来了。所以只要求出这N!中有多少个2多少个5相乘就好了,由于2的出现次数肯定是大于5的,所以只要求有多少个5相乘就好了。

    因为求的是N的阶乘,而 N! = 1*2*3*....*N

    那么:这N个数中能被5整除的个数 = N / 5

    比如N = 50 ,能被5整除的有 5 10 15 20 25 30 35 40 45 50 共10个,即50/5=10

    但别忘了25和50,他们可拆分成5*5和5*5*2,也就是说能被5^2整除的数会带来2个零(以此类推5的m次方会在末尾带来m个零)。

    所以50!末尾有10+2=12个“0”。

    所以额外还要求出这5的m次方的数的个数,我们可以从5到5*5到5*5*5 ... 慢慢往大的找。

    那么具体代码如下(借鉴于网络,2L的答案)

     1 int totalzero(int n)
     2 {
     3     int total = 0;
     4     while (n > 5)
     5     {
     6         n = (n - (n % 5)) / 5;
     7         total += n;
     8     }
     9     return total;
    10 }

    这里的第n次循环相当于求能被5^n整除的数有多少,并把结果相加。

    虽然每次循环后n的数值变了,但整体效果还是相当于在求能被5^n整除的数有多少。

    那么回答一下图中的问题:

    1,为什么N不同结果却相同:看代码很明显,末尾数字是01234或者56789的时候结果都是一样的,因为经过了一次 n - (n % 5) 末尾全都变成0了,接下来的运算都相同,必然得出相同的结果。

    2,具体产生编号的思路:

     1 #include <stdio.h>
     2 #include <string.h>
     3 
     4 int totalzero(int n)
     5 {
     6         int total = 0;
     7         while (n > 5)
     8         {
     9             n = (n - (n % 5)) / 5;
    10             total += n;
    11         }
    12         return total;
    13 }
    14 
    15 int main()
    16 {
    17     char Sequence[9] = { 0 };
    18     memset(Sequence, '0', 8);
    19     sprintf(Sequence,"%08d",totalzero(1024));
    20     printf("%s
    ", Sequence);
    21 
    22     return 0;
    23 }
    View Code
  • 相关阅读:
    Java equals()和hashCode()重写总结
    常见ORM框架理解
    struts2的第一个小页面
    Java开发StringBuilder类
    “中软综合项目实训”——把学生当员工培养
    中软寻梦
    软件开发学习的5大技巧
    从学生心理入手
    IT技术人员的职业发展方向
    驱动创新 引领未来
  • 原文地址:https://www.cnblogs.com/makejeffer/p/4841589.html
Copyright © 2020-2023  润新知