C - Count TheCarries
来源:互联网 发布:注册环保工程师知乎 编辑:程序博客网 时间:2024/05/17 05:13
C - Count TheCarries
现在给你两个数A与B (0<=A<=B<=1000000000),然后要求A与A+1相加,结果再与A+2相加,直到加到B为止。不过过程中做的加法都是数的二进制表示形式的加法。求做的所有加法的二进制进位的总数。比如A+(A+1)共有8次二进制进位,(2A+1)+(A+2)有9次二进制进位,那么A到A+2一共有17次二进制进位。
输入:有最多100000个实例,每个实例用两个整数A,B表示,A=B=0时,表示输入结束。
输出:输出每个实例的进位总数。
分析:对于任意给出的实例A,B只要依次求出X与Y相加时的进位个数就可以。然后再累加入总数即可。
任意X与Y数相加的二进制进位个数为:X的二进制位个数+Y的二进制位个数-(X+Y)的二进制位个数。比如:
011010
010110
110000
原本X有3个1,Y有3个1,结果(X+Y)只有2个1了,只有在进位的时候会发生原本2个1变成1个1的情况(从而少了一个1)。所有少了几个1就表示进位了几次。
对于从A到B的序列依次相加的二进制进位总数为:
【A的二进制位数+(A+1)的二进制位数+…B的二进制位数】—【A+(A+1)+…+B的和的二进制位数】
对于每个实例A与B,只要依次计算A,A+1,。。。B的二进制中1的个数,再减去(A+A+1,+…+B)的二进制位个数即可。
以下代码超时:
#include<cstdio>using namespace std;int bitcount(long long x){ if(x==0)return 0; returnbitcount(x/2)+(x&1);}int main(){ long longa,b; while(scanf("%lld%lld",&a,&b)==2&&a&&b) { longlong bit_sum=0,sum=0; for(longlong i=a;i<=b;i++) { sum+=i; bit_sum+=bitcount(i); } printf("%lld\n",bit_sum-bitcount(sum)); } return 0;}
解法二:现在想象从A到B所有的数都以二进制的形式叠加在一起相加:
1000111
1001000
1001001
1001010
Sum[64]=0000…4003122(一个数最多64位)
sum[64]保存数加的中间结果,sum[0]表示所有数在2^0的位上二进制的总个数,sum[i]表示所有数在2^i位上二进制的总个数。那么这些不同位上的1相加后进位个个数为:
2^0上的1相加产生的进位,加上 (2^1上的所有1 以及2^0上的1的进位 相加产生的进位),加上…
现在只要求出A到B序列所有数的1的sum表示即可。
如何求0到n的所有数的1的sum表示?
0到n的所有数的二进制和中,第2^i位上1的总数为:
n%(2^(i+1))-(2^i-1) > 0 时
[ n/(2^(i+1))]*(2^i)+n%(2^(i+1))-(2^i-1)
n%(2^(i+1))-(2^i-1) <= 0 时
[n/(2^(i+1))]*(2^i)
(自己分析一下2^0位,2^1位,2^2位看看有什么规律)计算一定要小心。
#include<cstdio>using namespace std;int get(int num[],long long n)//num[i]=j 表计算从0到n的数的二进制和(不进位) 中第2^i位的1的总个数为j个{ for(int i=0;i<64;i++)num[i]=0; int i; for(i=0;i<64;i++) { if((1LL<<i)>n)break; num[i]+= ( n/(1LL<<(i+1)) )*(1<<i) ; if( n%(1LL<<(i+1)) > (1LL<<i)-1 ) num[i] += n%(1LL<<(i+1)) - ((1LL<<i)-1); } return i;}int main(){ int a,b; while(scanf("%d%d",&a,&b)==2&&a&&b) { int num1[64],num2[64]; get(num1,a-1); get(num2,b); for(int i=0;i<64;i++)num2[i]-=num1[i]; long long sum=0; for(int i=0;i<64;i++) { sum +=num2[i]/2; num2[i+1]+=num2[i]/2; } printf("%I64d\n",sum); } return 0;}
- C - Count TheCarries
- C - Count TheCarries
- C - Count Color
- 204. Count Primes(C++)
- C++count算法(STL)
- [leetcode]Count Primes C语言
- Count
- COUNT
- count
- Count
- count
- count
- count
- count
- Count
- count
- Count
- simple ref count in C/C++
- PT100温度传感器调试
- 电脑太卡怎么办,最好别花钱
- htonl ntohl htons ntohs
- JDK中的二分查找算法
- 2014.1.11 C开发窗口程序Combo控件的应用
- C - Count TheCarries
- 《Start Developing iOS Apps Today》学习笔记(三)心得体会
- 点滴:Java Socket编程【转】
- 树的基本操作
- ARM汇编SWI
- cocos2d-x OpenGL Shader 图片特效处理
- hibernate将本地SQL查询结果封装成对象
- ZOJ-2548
- 十步完全理解SQL