zoukankan      html  css  js  c++  java
  • poj3252

    题意:问区间[a,b]中,有多少个数化成二进制后,0比1多。

    分析:以110100为例,先计算小于100000的有多少个,c(5,2)+c(5,1)。还需要计算100000~110100之间的数量。再将除最高位的1之外的最高的1改为0,以保证后面组合时出现的所有数字小于110100,形如10****。后四位组合数c(4,2)+c(4,1)。再将下一个1变为0,变为1100**。如此依次将各个1变为0,并固定1前面的位,可以帮助我们计算出所有在100000~110100之间的数量。

    View Code
    #include <iostream>
    #include
    <cstdio>
    #include
    <cstdlib>
    #include
    <cstring>
    usingnamespace std;

    longlong s, e;
    longlong f[50];

    longlong com(longlong n, longlong r)
    {
    if (n <=0)
    return1;
    if (n - r < r)
    r
    = n - r;
    longlong i, j, s =1;
    for (i =0, j =1; i < r; ++i)
    {
    s
    *= (n - i);
    for (; j <= r && s % j ==0; ++j)
    s
    /= j;
    }
    return s;
    }

    longlong cal(longlong a)
    {
    longlong num1, num0, bit =0, ret =0;
    num1
    = num0 =0;
    longlong x =1;
    while (x <= a)
    {
    x
    <<=1;
    bit
    ++;
    }
    for (int i =1; i < bit; i++)
    for (int j =0; j <= i /2-1; j++)
    ret
    += com(i -1, j);
    longlong pos = bit;
    x
    >>=1;
    num1
    ++;
    while (pos--, x >>=1)
    {
    if (x & a)
    num1
    ++;
    else
    {
    num0
    ++;
    continue;
    }
    for (longlong i = pos -1; num1 -1+ (pos -1- i)<= num0 +1+ i && i >=0; i--)
    ret
    += com(pos -1, i);
    }
    return ret;
    }

    int main()
    {
    //freopen("t.txt", "r", stdin);
    scanf("%lld%lld", &s, &e);
    printf(
    "%lld\n", cal(e +1) - cal(s));
    return0;
    }
  • 相关阅读:
    英文半字节压缩编码技术
    博弈翻硬币游戏
    POJ 2015 Permutation Code
    8051、ARM和DSP指令周期的测试与分析
    Huffman编码
    CentOS 命令提示符颜色及样式详解
    JAVA程序员面试32问
    面向抽象编程:接口和抽象类
    初学实用:实例讲解Java中的接口的作用
    C#和Java的区别
  • 原文地址:https://www.cnblogs.com/rainydays/p/2096290.html
Copyright © 2011-2022 走看看