题意:
给两个数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; }