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
把数字转化二进制,那么n<<1时,必须保证1的前一位为0,呢么依次类推1 10 101 1000 1001 1010 10000 10001 10010....
若把满足的数,并且二进制位数相等的保存下来,呢么满足斐波那契数列(可以手推)
因此保存斐波那契前58项的前缀和,每次在区间里比较,不断确定其所具有的最大进制位,然后减去(前缀和加1)(二进制中末尾全0特判)
依次类推,直到n<=0
#include <iostream> #include <algorithm> #include <cstring> #include <cstdio> #include <vector> #include <queue> #include <stack> #include <cstdlib> #include <iomanip> #include <cmath> #include <cassert> #include <ctime> #include <map> #include <set> using namespace std; #pragma comment(linker, "/stck:1024000000,1024000000") #define lowbit(x) (x&(-x)) #define max(x,y) (x>=y?x:y) #define min(x,y) (x<=y?x:y) #define MAX 100000000000000000 #define MOD 1000 #define pi acos(-1.0) #define ei exp(1) #define PI 3.1415926535897932384626433832 #define ios() ios::sync_with_stdio(true) #define inf 0x3f3f3f3f #define mem(a) (memset(a,0,sizeof(a))) #define ll long long ll fac[65],n,t; void init() { fac[0]=0; fac[1]=1;fac[2]=1; for(int i=3;i<=58;i++) fac[i]=fac[i-1]+fac[i-2]; fac[2]+=fac[1]; for(int i=3;i<=58;i++) fac[i]+=fac[i-1]; } int main() { init(); scanf("%lld",&t); while(t--) { scanf("%lld",&n); ll ans=0; while(n>0)//最后一定可以得到n<=0; { for(int i=1;i<=58;i++) { if(n>fac[i-1] && n<=fac[i]) { ans+=(ll)1<<(i-1); n-=fac[i-1]+1; break; } } } printf("%lld\n",ans); } return 0; }