HDU 4588--二进制的加法进位统计

该博客探讨了在二进制系统中,从一个数字a连续加1直至达到另一个数字b的过程中,所需的进位次数。通过分析二进制数的特性,可以找出解决问题的规律。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:

给两个数a b,问二进制情况下从a一直加1 直到b需要进多少位。


输入:

1 2
1 3
1 4
1 6


输出:


0
2
3
6

分析:

二进制只是由1和0组成,二进制下的各数都有规律可循。

9 8 7 6 5 4 3 2 1
0 0 0 0 0 0 0 0 0   (0)
0 0 0 0 0 0 0 0 1   (1)
0 0 0 0 0 0 0 1 0   (2)
0 0 0 0 0 0 0 1 1   (3)
0 0 0 0 0 0 1 0 0   (4)
0 0 0 0 0 0 1 0 1   (5)
0 0 0 0 0 0 1 1 0   (6)
0 0 0 0 0 0 1 1 1   (7)
0 0 0 0 0 1 0 0 0   (8)
: : :::::::
: : : : : : :  :
就这样会发现规律:
就是第一行就是1和0交替出现,
第二竖行是00 11交替出现,
第三竖行是0000 1111交替出现等等
计算1的个数,然后求需要进位的值....
拆成二进制来看的话,考虑第一位,假设从1~b有x1个数的第一位是1,从1~a-1有x2个数的第一位是1,那么从a~b就有(x1-x2)个数第一位是1,那么在第一位需要进位的次数就为(x1-x2)/2。假设从a~b有x3个数第二位是1,那么在第二位需要进位的次数就为((x1-x2)/2 + x3)/2。以此类推。
代码:
#include <bits/stdc++.h>
using namespace std ;

int main()
{
    long long num1[70],num2[70],a,b;
    while(~scanf("%I64d%I64d",&a,&b))
    {
        memset(num1,0,sizeof(num1));
        memset(num2,0,sizeof(num2));
        b++;
        int tmp=b;
        for(int i=0,k=2; i<=70; i++,k*=2)
        {
            num1[i]=a/k*k/2+(a%k>=k/2?a%k-k/2:0); //1-a各位1的个数
            num2[i]=b/k*k/2+(b%k>=k/2?b%k-k/2:0); //1-b+1各位1的个数
            tmp/=2;
            if(!tmp)
                break;
        }
        long long num=0;
        for(int i=0; i<70; i++)
        {
            num+=(num2[i]-num1[i])/2;
            num2[i+1]+=(num2[i]-num1[i])/2;
        }
        printf("%I64d\n",num);
    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值