• 排列与二进制(暑假每日一题 33)


    组合数学中,我们学过排列数。

    n n n 个不同元素中取出 m ( m < = n ) m(m<=n) mm<=n个元素的所有排列的个数,叫做从 n n n 中取 m m m 的排列数,记为 p ( n , m ) p(n,m) p(n,m)

    具体计算方法为 p ( n , m ) = n ( n − 1 ) ( n − 2 ) … … ( n − m + 1 ) = n ! / ( n − m ) ! p(n,m)=n(n−1)(n−2)……(n−m+1)=n!/(n−m)! p(n,m)=n(n1)(n2)……(nm+1)=n!/(nm)!(规定 0 ! = 1 0!=1 0!=1)。

    n n n m m m 不是很小时,这个排列数是比较大的数值,比如 p ( 10 , 5 ) = 30240 p(10,5)=30240 p(10,5)=30240

    如果用二进制表示为 p ( 10 , 5 ) = 30240 = ( 111011000100000 ) b p(10,5)=30240=(111011000100000)_b p(10,5)=30240=(111011000100000)b,也就是说,最后面有 5 5 5 个零。

    我们的问题就是,给定一个排列数,算出其二进制表示的后面有多少个连续的零。

    输入格式
    输入包含多组测试数据。

    每组数据占一行,包含两个整数 n , m n,m n,m

    最后一行为 0 0,表示输入结束,无需处理。

    输出格式
    每组数据输出一行,一个结果,表示排列数 p ( n , m ) p(n,m) p(n,m) 的二进制表示后面有多少个连续的零。

    数据范围
    1 ≤ m ≤ n ≤ 10000 , 1≤m≤n≤10000, 1mn10000,
    输入最多包含 100 100 100 组数据。

    输入样例:

    10 5
    6 1
    0 0
    
    • 1
    • 2
    • 3

    输出样例:

    5
    1
    
    • 1
    • 2

    • 10 10 10 进制时,要求数的右边有几个 0 0 0,就是求数有几个因子 10 10 10
      同理二进制就是求数有几个因子 2 2 2

    • 如何求 n ! n! n! 中有几个因子 p p p
      n ! = n ∗ ( n − 1 ) ∗ ( n − 2 ) ∗ . . . ∗ 1 n! = n * (n - 1) * (n - 2) * ... * 1 n!=n(n1)(n2)...1
      等价于求 n / p + n / p 2 + . . + n / p k n/p + n/p^2 + .. + n/p^k n/p+n/p2+..+n/pk
      n / p n / p n/p 求的是 1   n 1~n 1 n 中能被 p p p 整除的数的个数
      n / p 2 n / p^2 n/p2 求的是 1   n 1~n 1 n 中能被 p 2 p^2 p2 整除的数的个数
      而能被p^2整除的数 包含有 2 2 2 p p p 的因子
      但是这些数也是 p p p 的倍数,所以在 n / p n / p n/p 时已经加了一遍
      此时只需要 + n / p 2 + n / p^2 +n/p2 即可。
      其它的同理

    #include
    
    using namespace std;
    
    int f(int n, int p){
        
        int res = 0;
        while(n) res += n / p, n /= p;
        return res;
    }
    
    int main(){
        
        int n, m;
        while(cin >> n >> m, n)
            cout << f(n, 2) - f(n - m, 2) << endl;
        
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
  • 相关阅读:
    K-近邻算法
    不同局域网下使用Python自带HTTP服务进行文件共享「端口映射」
    大规模神经网络的实现(什么是异步梯度下降?怎样进行模型压缩?)
    Vue3+node.js网易云音乐实战项目(七)
    Hive和Kylin性能对比_大数据培训
    【lwip】06-网络接口层分析
    P2PNet-Soy原理梳理
    docker容器持久化
    08.URL调度器示例
    C语言中什么是算术运算?什么是关系运算?什么是逻辑运算?什么是二进制运算?
  • 原文地址:https://blog.csdn.net/qq_46456049/article/details/126477834