1+2=3?

链接:https://www.nowcoder.com/acm/contest/91/F
来源:牛客网

题目描述

小Y在研究数字的时候,发现了一个神奇的等式方程,他屈指算了一下有很多正整数x满足这个等式,比如1和2,现在问题来了,他想知道从小到大第N个满足这个等式的正整数,请你用程序帮他计算一下。

(表示按位异或运算)

输入描述:

第一行是一个正整数,表示查询次数。

接着有T行,每行有一个正整数,表示小Y的查询。

输出描述:

对于每一个查询N,输出第N个满足题中等式的正整数,并换行。
示例1 

输入

4
1
2
3
10

输出

1
2
4
18

解法
这道题目首先一拿到,先输出看看满足条件的数据是否有没有什么规律,可以发现只要是2^n都满足要求,并且里面还隐藏着斐波那契数列的规律。
1
2
4 5
8 9 10
16 17 18 20 21
32 33 34 36 37 40 41 42
64 65 68....
以2^n开头的每一排都有斐波拉契数F(i)个,且每一个数的二进制形式中1都是不能连续的,且能观察到后面的数都是由前面的数生成的,例如:36=32+4,42=32+10
这个解法就相当于判断每一位上是不是1,如果说是1,则下一位肯定不是1。
#include<iostream>
using namespace std;

typedef long long ll;
ll f[105];

int main(){
    f[1] = f[0] = 1;
    for (int i = 2; i <= 63; i++)
        f[i] = f[i - 1] + f[i - 2];
    int T;
    ll n;
    scanf("%d",&T);
    while (T--){
        scanf("%lld",&n);
        n++;
        ll o = 0;
        for (int i = 63, v; i >= 1; i=v){
            if (f[i] < n){
                o += (1LL << (i - 1));
                n -= f[i];
                v = i - 2;
            }
            else{
                v = i - 1;
            }
        }
        printf("%lld\n",o);
    }
}
posted @ 2018-04-19 23:52  小白兔云  阅读(517)  评论(0)    收藏  举报