枚举任意相邻两位都是1的次数,这个次数是这两位前面的数的方案数乘上后面的数的方案数,如果这两位最大值都是1,那么还要多加上一个后面数的方案数。答案会爆long long,要用高精度。
输出固定位数的整数,不够用0在前面补齐:
printf("%04d",n);//固定4位
代码:
//
// main.cpp
// 11645 Bits
//
// Created by Baoli1100 on 15/2/15.
// Copyright (c) 2015年 Baoli1100. All rights reserved.
//
#include <iostream>
using namespace std;
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#define LL long long
LL a[70];
bool k[70];
struct Bigint{
vector<int> data;
Bigint(){}
void formal(){
if(data.empty()) data.push_back(0);
while(data.size()>1&&data.back()==0){
data.pop_back();
}
}
Bigint(LL n){
while(n){
data.push_back(n%10000);
n/=10000;
}
formal();
}
void Print(){
int len=data.size();
printf("%d",data[len-1]);
for(int i=len-2;i>=0;i--){
printf("%04d",data[i]);
}
}
int Len(){
return data.size();
}
int & operator[](int n){
while(n>=Len()){
data.resize(Len()*2+1,0);
}
return data[n];
}
void Set(LL n){
data.resize(0);
while(n){
data.push_back(n%10000);
n/=10000;
}
}
};
Bigint operator +(Bigint &x,Bigint &y){
Bigint res;
int len=max(x.Len(),y.Len());
for(int i=0;i<len;i++){
res[i]+=x[i]+y[i];
res[i+1]+=res[i]/10000;
res[i]%=10000;
}
res.formal();
return res;
}
Bigint solve(LL num){
int len=0;
memset(k,0,sizeof(k));
LL t=num;
while(num){
k[++len]=(num&1);
num>>=1;
}
num=t;
if(len<2){
Bigint res(0);
res.formal();
return res;
}
Bigint res(0);
LL left=0,right=num%a[len-2];
Bigint tmp(0);
for(int i=len;i>1;i--){
left*=2;
if(k[i+1]) left++;
right=num%a[i-2];
tmp.Set(left*a[i-2]);
res=res+tmp;
if(k[i]&&k[i-1]){
tmp.Set(right+1);
res=res+tmp;
}
}
res.formal();
return res;
}
int main(){
a[0]=1;
for(int i=1;i<=62;i++){
a[i]=a[i-1]*2;
}
LL n;
int kase=1;
while(~scanf("%lld",&n)){
if(n<0) break;
Bigint res=solve(n);
printf("Case %d: ",kase++);
res.Print();
printf("\n");
}
return 0;
}