1. 程式人生 > >[ 9.22 ]CF每日一題系列—— 484A Bits

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

pac () can nbsp 貪心 每日 結果 scan typedef

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

  

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