Problem - 1632C - Codeforces
伊戈尔正在读11年级。明天他将不得不写一份信息学测试,由学校最严格的老师帕维尔-杰尼索维奇负责。
伊戈尔知道测试将如何进行:首先,老师会给每个学生两个正整数a和b(a<b)。之后,学生可以应用以下任何一种操作,次数不限。
a:=a+1(将a增加1)。
b:=b+1 (将b增加1)。
a:=a | b(用a和b的位数OR替换a)。
为了在考试中得到满分,学生必须告诉老师使a和b相等所需的最少运算次数。
伊戈尔已经知道老师会给他哪些数字。请帮助他算出使a等于b所需的最少运算次数。
输入
每个测试包含多个测试案例。第一行包含测试用例的数量t(1≤t≤104)。测试用例的描述如下。
每个测试用例的唯一一行包含两个整数a和b(1≤a<b≤106)。
保证所有测试用例的b之和不超过106。
输出
对每个测试案例打印一个整数--使a和b相等所需的最小操作数。
例子
inputCopy
5
1 3
5 8
2 5
3 19
56678 164422
输出拷贝
1
3
2
1
23329
注意
在第一个测试案例中,应用第三次操作是最好的。
在第二个测试案例中,最理想的是应用第一次操作三次。
在第三个测试案例中,最好先进行第二次操作,然后再进行第三次操作。
题解:
让a,b相等的最大值应该为b - a
由于a|b >= b,所以异或操作顶多使用一次
异或情况相等本质就是二进制位的a与b此时的后缀相等,有了这个结论
我们就能知道要么是(a +某个数) or b = b,要么是(b + 某个数 )or a = (b + 某个数)
某个数的范围就是0~b-a,因为让其相等最大值就是b - a
当然也可能0~b-a中没有哪个数能使其 or 相等
那么答案就是b - a
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define int long long
void solve()
{
int a,b;
cin >> a >> b;
int res = b - a;
for(int i = 0;i <= b - a;i++)
{
if(((a+i)|b) == b||(a|(b+i)) == (b + i))
{
res = min(res,i + 1);
break;
}
}
cout<<res<<'\n';
}
signed main()
{
// ios::sync_with_stdio(false);
// cin.tie(0);
// cout.tie(0);
int t = 1;
cin >> t;
while(t--)
{
solve();
}
}
//1 10 11
//001
//010
//011
//100