反复读密码锁

链接: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(0n1018),表示含义见题目描述。

输出描述:

一共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)就可以了。

posted on 2022-03-10 18:01  衔白棋子的黑猫  阅读(87)  评论(0)    收藏  举报

导航