Uva 11645 - Bits 解题报告(递推+大数)

来源:互联网 发布:哈萨克歌软件 编辑:程序博客网 时间:2024/06/04 19:58

Problem J
Bits 
Input: 
Standard Input

Output: Standard Output

 

bit is a binary digit, taking a logical value of either "1" or "0" (also referred to as "true" or "false" respectively).  And every decimal number has a binary representation which is actually a series of bits. If a bit of a number is “1” and it's next bit is also “1” then we can say that the number has a 1 adjacent bit. And you have to find out how many times this scenario occurs for all numbers up to N.

 

Examples:

            Number           Binary                         Adjacent Bits

            12                    1100                            1

            15                    1111                            3

            27                    11011                          2

 

Input

For each test case, you are given an integer number (0 <= N <= ((2^63)-2)), as described in the statement. The last test case is followed by a negative integer in a line by itself, denoting the end of input file.

 

Output

For every test case, print a line of the form “Case X: Y”, where X is the serial of output (starting from 1) and Y is the cumulative summation of all adjacent bits from 0 to N.

 

Sample Input                             Output for Sample Input

0

6

15

20

21

22

-1

Case 1: 0

Case 2: 2

Case 3: 12

Case 4: 13

Case 5: 13

Case 6: 14



    解题报告; 自己想的,不过WA了几次在高精度上。

    对于一个数,我们先将其转化为二进制的形式。例如110110001。从高位向低位遍历。第一位是1,那么所有0********的串都符合条件,我们求出********的串中有多少11即可。对于这种串中有多少11,我们可以用概率的方式去求。第一位是1的概率是1/2,第二位是1的概率也是1/2,那么1,2位组成11的概率是1/4,总串数是2^8,那么********串中的11的数量为2^8*(1/4*7)。另外,如果遍历到当前数是1,上一位也是1,那么后面的数字都符合条件了(例如110000000到110110001),答案加上这样的数。

    简单写了个高精度,代码如下:

#include <cstdio>#include <cstring>#include <algorithm>#include <iostream>using namespace std;typedef long long LL;const int K = 10000;const int M = 10;const char show[] = "%04d";struct Bignum{    LL a[M*2];    Bignum()    {        memset(a, 0, sizeof(a));    }    Bignum(LL num)    {        memset(a, 0, sizeof(a));        int t=0;        while(num)            a[t++]=num%K,num/=K;    }    Bignum operator+(const Bignum& b)    {        Bignum c;        for(int i=0;i<M;i++)            c.a[i]=a[i]+b.a[i];        c.metain();        return c;    }    Bignum operator+(LL num)    {        return *this+Bignum(num);    }    void metain()    {        for(int i=0;i<M;i++) if(a[i]>=K)            a[i+1]+=a[i]/K,a[i]%=K;    }    Bignum operator*(const Bignum& b)    {        Bignum c;        for(int i=0;i<M;i++) for(int j=0;j<M;j++)            c.a[i+j] += a[i]*b.a[j];        c.metain();        return c;    }    void output()    {        int t=M*2;        while(a[--t]==0 && t>0);        printf("%lld", a[t--]);        for(int i=t;i>=0;i--)            printf(show, abs(a[i]));        puts("");    }};int dd[1000];int dNum=0;LL two[1000];void init(){    two[0]=1;    for(int i=1;i<=64;i++)        two[i]=two[i-1]*2;}void decomposition(LL n){    dNum=0;    memset(dd, 0, sizeof(dd));    while(n>0)        dd[dNum++]=n%2,n>>=1;}int cas=1;void work(LL n){    decomposition(n);    Bignum ans(0);    for(int i=dNum-1;i>=0;i--)    {        if(dd[i]==1)        {            if(i>=2)                ans=ans+Bignum(two[i-2])*(i-1);            if(dd[i+1]==1)                ans=ans+(n%two[i]+1);        }    }    printf("Case %d: ", cas++);    ans.output();}int main(){    init();    LL n;    ios::sync_with_stdio(false);    while(cin>>n && n>=0)        work(n);}


0 0