Description:
给你一个l,r的区间让你找一个最小的x并且其二进制数要包含最多的1位,输出它的十进制
Solution:
我本来就是贪心,但是贪大了,想1一直往上添加1,但是忘记了0在中间的情况,考虑好了之后,发现这样贪是错误的,因为越往后位数越大,所以你最后的结果只能是1,11,111,1111,11111,而不可能是10,100,1001,10010,所以应该从后往前贪,这也是我们十进制转二进制的人工算法吧算是,十进制转二进制,手算的时候,就是一步一步确定最高位的1在哪里,
code
从满1开始用异或变0,如果变成了0小于l,这是不允许的,第一个满足条件的就是最好的,可能你有疑惑,不是要最小的x吗,你想想110,和101,区间假如就是[5,6]从111开始第一位不能变成0,第二位可以101就结束了,所以从后往前变零就是从最小满足到最大满足的考虑了
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> using namespace std; typedef long long int ll; int main() { ll num; ll l,r; int t; scanf("%d",&t); while(t--) { num = (1LL << 62) - 1; scanf("%lld%lld",&l,&r); for(int i = 61;i >= 0;i--) { //即时退出保证1是最多的 if(num >= l && num <= r) break; if((num ^ (1LL << i)) >= l) num ^= (1LL << i); } printf("%lld ",num); } return 0; }