2013 ACM-ICPC南京全國邀請賽
阿新 • • 發佈:2019-01-25
Count The Carries
One day, Implus gets interested in binary addition and binary carry. He will transfer all decimal digits to binary digits to make the addition. Not as clever as Gauss, to make the addition from a to b, he will add them one by one from a to b in order. For example, from 1 to 3 (decimal digit), he will firstly calculate 01 (1)+10 (2), get 11,then calculate 11+11 (3),lastly 110 (binary digit), we can find that in the total process, only 2 binary carries happen. He wants to find out that quickly. Given a and b in decimal, we transfer into binary digits and use Implus's addition algorithm, how many carries are there?Input
Two integers a, b(0<=a<=b<1000000000), about 100000 cases, end with EOF.
Output
One answer per line.
Sample Input
1 2
1 3
1 4
1 6
Sample Output
0
2
3
6
題意:給出a b,把a--b中的所有數轉成二進位制,然後相加,求相加過程中有幾次低位向高位進位
3位上每隔16數就有8個1
所以只要求每一位上1的個數之和,後面在處理就行 程式碼:
#include <iostream> #include <stdio.h> #include <cmath> #include <cstring> #include <algorithm> #include <vector> #include <map> using namespace std; const int M=1e5+5; const int mod=1e9+7; int num1[70]; int num2[70]; void cal(int a[],int n)//0-n每個數位上1的和 { int i,temp; temp=1; n++; for(i=0;i<64;i++) { if(temp>n)break; temp*=2; a[i]+=(n/temp)*(temp/2); if(n%temp>temp/2)//餘數大於temp/2,後面還有n%temp-temp個1 a[i]+=n%temp-temp/2;//或者a[i]+=n%(tmp/2); } } int main() { int a,b,i; long long sum; while(scanf("%d%d",&a,&b)!=EOF) { memset(num1,0,sizeof(num1)); memset(num2,0,sizeof(num2)); cal(num1,a-1); cal(num2,b); for(i=0;i<64;i++) num2[i]-=num1[i]; sum=0; for(i=0;i<63;i++) { sum+=num2[i]/2; num2[i+1]+=num2[i]/2; } printf("%lld\n",sum); } return 0; }