zoukankan      html  css  js  c++  java
  • 算法笔记-2019/11/1

    一. 求N!末尾有几个0

    因为影响生成0的是2和5的倍数,显然这些数的分解数含2的因子多于含5的因子,因此我们可以得出一个结论,N!的分解数中有多少个因子5,末尾就有多少个0,所以实际上就是去求N里面有多少个5。
    采用层层剥皮法去求,先以5为步长,执行一次循环,求出含5的个数(个数为N/5取整),再求出含25的个数(因为一个数可以被5整除2次),有个问题还需要注意,25,125也是5的倍数,125也是25的倍数……一直到步长大于或等于N退出循环。
    例求2016!后面0的个数呢?
    同样按照上面的方法。
    5的倍数个数为:
    2016/5 = 403个
    25的倍数个数为:
    403/5 = 80个
    125的倍数的个数为:
    80/5 = 16个
    625的倍数的个数为: 16/5 = 3个。
    所以可以得出2016!后面0的个数为:403+80+16+3 = 502个.
    代码如下

    int ZeroTrail(int n)//计算n!的0的个数 
    {
      int count = 0;
      while(n) 
      {
        count+=n/5;
        n/=5;
      }
      return count;
    }

    二、近似整数

    【题目描述】近似整数(Approximation.cpp/c/pas) POJ 1650给定一个浮点数A和一个整数L,求在范围[1,L]内的两个整数n和d,使得n/d能近似等于A,且使误差|A-n/d|最小。
    【输入格式】第一行为一个浮点数A,第二行为一个整数L。
    【输出格式】两个整数n和d。
    【输入样例】3.1415926535897910000
    【输出样例】355 113

    算法分析:可以使用常规的二分法求解,也可以考虑追赶法求解。
    追赶法:不断比较得出min(A-n/d),在n/d>A时d++,相反则n++,即d和n的追赶问题。

    while(n <= L && d <= L)//在o~这个范围之内
    {
        cha = f - (double)n / d;//与浮点数进行比较
        if (min > fabs(cha))//差值比min更小就更新
        {
            min = fabs(cha);
            ansn = n;
            ansd = d;
        }
        if (cha > 0)//后面小了,应当增大分子
            n++;
        else
            d++;//否则减小分母
    }
    printf("%d %d
    ", ansn, ansd);
    
  • 相关阅读:
    VIM文本替换命令
    VIM格式化代码(How to format code with VIM)
    字符串匹配的Boyer-Moore算法
    Java中数组的遍历
    UVa10723
    uva242,Stamps and Envelope Size
    UVa1630,Folding
    uva1629,Cake Slicing,记忆化搜索
    uva 10118,记忆化搜索
    uva10003
  • 原文地址:https://www.cnblogs.com/zdw20191029/p/14553391.html
Copyright © 2011-2022 走看看