HDU 4588

Count The Carries

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 1538    Accepted Submission(s): 540


Problem Description
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
 
題意:給定兩個十進制數,求二進制中,從x加到y的二進制進了多少位。

思路:把這些數字的二進制縱向羅列出來,然後一位一位的把和加起來,最終得到總的進位數。從1到x,第i位上1的總數是x左移i+1位再右移i位後得到的(在第0位上,1和0以1010101010的週期出現,並且每個週期一個1,在第1位上,1和0以11001100的週期出現,並且每個週期2個1,以此類推,則第n位上的1的個數是x/2^n*2^(n-1),即先左移n+1位,再右移n位),在這裏就卡了很久。。。如果x在i位上面上是1,特殊判斷一下,求一下週期以外的1的個數,這個時候的1的個數是a%(1<<k)+1。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
ll val(ll a,int k)
{
    if(a == -1) return 0;
    ll t = ((a>>(k+1))<<k);
    if(a&(1ll<<k)) t+=a%(1ll<<k)+1;
    return t;
}
int main()
{
    ll ans,carry;
    int x,y;
    while(scanf("%d%d",&x,&y)!=EOF)
    {
        ans = 0;
        carry = 0;
        for(int i = 0;i < 63;i++)
        {
            carry += val(y,i) - val(x-1,i);
            carry /= 2;
            ans += carry;
        }
        printf("%I64d\n",ans);
    }
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章