2022 ICPC网络赛第一场-D Find the Number

Let's call a number x good if x is an interger and ctz(x)=popcount(x).

ctz(x) is the number of trailing zeros in the binary representation of x.

popcount(x) is the number of 1's in the binary representation of x.

For example:

ctz(12)=ctz(11002​)=2 and popcount(12)=popcount(11002​)=2, so 12 is a good number.

Now you are given an interval [l,r], you need to find a good number in it. If there are multiple solutions, print any of them; if there is no solution, print −1 instead.

输入样例:

5
38 47
57 86
23 24
72 83
32 33

输出样例:

-1
68
-1
-1
-1

 题意:

        把一个数字展开成二进制的,如果末尾0等于整个二进制中1的个数,那么这个数字就是一个"good number"

求某个区间内的任意"good number",没有则输出 -1

遇事不决先打个表,10e9内的"good number"总数才5e5个

emmmm,这道题就直接暴力

二进制最多30位,通过位运算可以很方便的得出所有数字,最后二分一下

对称情况

只需要枚举2^15 次就行

 不对称情况

左边最多枚举28位,但右边只能2位,当枚举总位数大于30时需要剪枝

 

代码

#include <iostream>
#include <algorithm>
using namespace std;
long long arr[505000], cnt = 0;
long long l, r, T;

void init() {
	for (long long i = 1; i <= (1 << 28); i++) {
		bool f=true;
		if (!(i & 1))
			continue;
		long long p = i, p1 = 0;
		while (p) {
			p &= (p - 1);
			p1++;
			if(i<<p1 > 1e9){
				f=false;
                break;
			}
		}
		if (f && i << p1 <= 1e9) {
			arr[cnt++] = (i << p1);
		}
	}
	sort(arr, arr + cnt);
}

int main() {
	init();
	scanf("%ld", &T);
	while (T--) {
		scanf("%ld%ld", &l, &r);
		long long *ans = lower_bound(arr, arr + cnt, l);
		if (*ans <= r && ans != arr + cnt) {
			printf("%ld\n", *ans);
		} else {
			printf("-1\n");
		}
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值