2020年西北工业大学 F-反复读密码锁

题目在这里:题目
这道题开始想了一种直接硬做的方式,不过发现有数据量过大会超过数据和string的范围,所以只能选择找规律。
首先,先写一段:01101001100101101001011001101001…
根据题目描述可以找到一个4个数字的循环,将这两种四个数字的组合再整合程一个新的符号组合即出现ABBABAAB,没错又是四个符号一循环的规律,那就是规律:一个二进制的递推式,那么我们只需要按照数字推回去即可
对于任何一个数字n都可以这样理解
对于任何一个n来说这个规律都是成立的,所核心代码比较简单的,不过这里需要用到一个函数high_bit(我也不会,直接搞得模板,想了解的可以去搜一下),具体实现为:

long long high_bit(long long x){ 
	x >>= 1;
	x = x|(x>>1);
	x = x|(x>>2);
	x = x|(x>>4);
	x = x|(x>>8);
	x = x|(x>>16);
	x = x|(x>>32);
	x++;
	return x;
}

有了这个就可以写完整代码,用的就是对n不断一位除数取余,知道n最后变成1或者2,这里又有一个注意的点(原题目题意给第n个数之后的‘后’字做了加粗):我们要求的是n+1,所以代码如下:

#include<bits/stdc++.h> 
using namespace std;
long long high_bit(long long x){//模板。。。。。。 
	x >>= 1;
	x = x|(x>>1);
	x = x|(x>>2);
	x = x|(x>>4);
	x = x|(x>>8);
	x = x|(x>>16);
	x = x|(x>>32);
	x++;
	return x;
}
long long search(long long n){
	if (n == 1)	return 0;
	if (n == 2)	return 1;
	long long f = high_bit(n);
	if (f == n){//移位 
		n >>= 1;
	}else{
		n -= f;
	}	
	return !search(n);
}
int main(){
	int t;
	scanf("%d",&t);
	while(t--){
		long long n;
		scanf("%lld",&n);
		printf("%d\n",search(n+1));
	}
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值