#include<iostream>
using namespace std;
int main()
{
int t;
cin >> t;
while(t --)
{
int a, b; cin >> a >> b;
int ans = b - a; //最原始的方案
for(int a1 = a; a1 < b; a1 ++) //枚举每个a`
{
int b1 = 0; //直接构造b`
//1e6的最高位是20
for(int i = 21; i >= 0; i --) //满足 b`>b>a`&&min(a`|b`=a`)
if(b >> i & 1)
b1 ^= (1 << i);
else
if(a1 >> i & 1)
{
b1 ^= (1 << i);
break; //保证b`大于b,且得到最小a`|b`
}
ans = min(ans, a1 + 1 - b - a + (a1 | b1));
}
cout << ans << endl;
}
return 0;
}
官方采用构造b1的方式来求解。我们首先知道操作三只能再最后一步用且需要满足a < b,又因为这道题数据范围特别小(详情见题,练练英语阅读),所以采用枚举暴力。
假设我们得到了一对a1b1,则操作步数 == (a′−a)+(b′−b)+((a′ | b′)−b′)+1 = a′+(a′ | b′)+(1−a−b),所以只用找a′+();
所以只用求最小的a′ | b′,我们可以设ans = b - a,每次令a加一得到a1(枚举a1但要小于b),然后然后对每一种a′ | b′做min操作,得到最小答案。