题目链接:https://www.nowcoder.com/acm/contest/105/D
题目: 意思是将x表示成第i位的位权为Fibonacci[i]的01字符串,在将01字符串表示的
2进制数转化的10进制数输出(有多种表示,输出最小的)。
思路: 找到最低的最高位,一步步缩减x,直到x为0!
1、前i-1位全为1表示的数<=x<前i位全为1表示的数,x的最高位最小为i。这种
Fibonacci进制的01字符串能表示出1~sum of 1-i Fibbonacci ,是连续的,所以
缩减后的x能够被表示!
预处理出所有前i个Fibbonacci数之和,找x的最高位用lowwer_bound( ),二分找出最高位it
/*
18湘潭acm校赛 D、Fibonacci进制
*/
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <map>
#include <vector>
#include <set>
#define llt long long
using namespace std;
const int Size =100;
int cnt ;
llt Sum[Size],Fibonacci[Size];
void init(){
Sum[0] = 0;
Fibonacci[0] = 1;
Sum[1] = Fibonacci[1] = 1;
int i;
for(i=2;;++i){
Fibonacci[i] = Fibonacci[i-1] +Fibonacci[i-2];
Sum[i] = Sum[i-1] + Fibonacci[i];
if(Sum[i]>1e9) break;
}
cnt = i+1;
//cout<<i<<endl;
}
int main(){
init();
int T;
scanf("%d",&T);
while(T--){
llt x;
scanf("%lld",&x);
llt ans = 0;
while(x){
int it = lower_bound(Sum,Sum+cnt,x)-Sum;//找最高位
//cout<<Fibonacci[it]<<endl;
x -= Fibonacci[it];
ans += (1ll<<(it-1));//最高位转化为2进制的权值
}
printf("%lld\n",ans);
}
return 0;
}