反复读密码锁
链接:https://ac.nowcoder.com/acm/contest/11290/F
来源:牛客网
题目描述
比那瑞星人把你锁在了一个房间里圈养,用“比那瑞锁”将唯一的出口锁住,这个锁只有0,1两个按键,密码也只有0,1两个数字,一个密码用一次就会自动重置,难道这就是传说中的一次一密?你列出了每次他输入的每一个数字:
01101001100101101001011001101001...
突然醍醐灌顶,初始时,序列sss为空,其生成的规律是这样的:
- 如果sss为空,那么s="0"s="0"s="0".
- 如果sss不为空,就在sss后面再添加~s这个序列。~s表示将sss序列中的0变为1,1变为0.
你想知道这个密码锁第n次使用后,下一个密码是什么。
输入描述:
第一行是一个整数T(T(T(1<=T<=1001<=T<=1001<=T<=100))),表示测试数据组数。
接下来的T行,每行一个数字n(0≤n≤1018)n(0 \le n \le 10^{18})n(0≤n≤1018),表示含义见题目描述。
输出描述:
一共T行,每行一个0或者1.
#include<cstdio> using namespace std; int T; long long n; inline bool read(ll &num){char in;bool IsN=false;in=getchar();if(in==EOF) return false;while(in!='-'&&(in<'0'||in>'9')) in=getchar();if(in=='-'){ IsN=true;num=0;}else num=in-'0';while(in=getchar(),in>='0'&&in<='9'){num*=10,num+=in-'0';}if(IsN) num=-num;return true;} int main() { scanf("%d",&T); while(T--) { scanf("%lld",&n); int l=0,cnt=0; while(n) { if(n%2==0) cnt++; n/=2; l++; } if(cnt%2==l%2) printf("0\n"); else printf("1\n"); } return 0; }
简言之就是:开始是0 然后每次后面接一个取反的串,长度变成二倍,问第n+1位是几。
规律:n的二进制表示下 0的个数和二进制的长度都是奇数/偶数,第n+1位就是0;否则一奇一偶了就是1
说实话,太难找了,根本没思路。
顺便抄一个快读的模板:
inline bool read(ll &num){char in;bool IsN=false;in=getchar();if(in==EOF) return false;while(in!='-'&&(in<'0'||in>'9')) in=getchar();if(in=='-'){ IsN=true;num=0;}else num=in-'0';while(in=getchar(),in>='0'&&in<='9'){num*=10,num+=in-'0';}if(IsN) num=-num;return true;}
然后read(x)就可以了。
浙公网安备 33010602011771号