POJ 3252 Round Numbers(数论)

201 篇文章 10 订阅

Description
问区间[a,b]中,有多少个数化成二进制后,0比1多
Input
两个整数a,b
Output
输出区间[a,b]中有多少个数的二进制形式0比1多
Sample Input
2 12
Sample Output
6
Solution
以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之间的数量
Code

#include<iostream>
#include<stdio.h>
int s,e,C[33][33]={{0}};
int count(int n)
{
    if(n<=1)
        return 0;
    int i,j,res=0,num[33]={0},len=0,zero=0,one=1;//最高位显然是1 
    while(n)//将n转化成二进制 
    {
        num[len++]=n&1;
        n>>=1;
    }
    for(i=2;i<len;i++)//先将小于n的所有最高位为1且其他位都为0的数计算出来 
        for(j=(i+1)>>1;j<i;j++)
            res+=C[i-1][j];
    for(i=len-1;i>0;i--)
        if(num[i-1])//若某位为1,则固定前位将该位变为0 
        {
            for(j=i-1;i-1-j+one<=j+zero+1;j--)
                res+=C[i-1][j];
            one++;//前位1个数加一 
        }
        else//前位0个数加一 
            zero++;
    return res+(zero>=one);
}
int main()
{
    int i,j;
    C[0][0]=1;
    for(i=1;i<33;i++)//打表 
    {
        C[i][0]=1;
        for(j=1;j<=i;j++)
            C[i][j]=C[i-1][j-1]+C[i-1][j];
    }
    while(scanf("%d%d",&s,&e)!=EOF)
        printf("%d\n",count(e)-count(s-1));
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值