2018年湘潭大学程序设计竞赛 D、Fibonacci进制 (思维题)

题目链接: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;
}

猜你喜欢

转载自blog.csdn.net/qq_38786088/article/details/80193720