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");
}
}
}