[ 9.22 ]CF每日一题系列—— 484A Bits

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\n",num);
    }
    return 0;
}

  

猜你喜欢

转载自www.cnblogs.com/DF-yimeng/p/9689456.html