问题描述:
给定两个正整数a和6,请你找到一个非负整数满足x 0<=x<=b,使得x 与 a 的异或值最大。 异或指的是位运算中的异或,对两个二进制数字的每一位进行运算,若两位相同,则异或后的值为 0,否则为1。
输入描述: 输入一行包含两个正整数 a,b(1 <= a,b <= 10^9)
输出描述 :输出一行一个正整数表示异或的最大值。
示例输入1: 3 6
输出: 7
说明: 从 0~ 6中选择一个数字 4,4和3异或得到 7,这是最大的异或结果。
代码分析:
1.输入处理:
Scanner in = new Scanner(System.in);
long a = in.nextLong();
long b = in.nextLong();
in.close();
- 使用
Scanner
从标准输入读取两个正整数a
和b
。 - 关闭
Scanner
以释放资源。
2.初始化变量:
long x = 0;
boolean flag = false;
x
:用于构建最终满足条件的整数x
,初始值为0
。flag
:标志位,用于指示在构建x
时是否已经偏离了b
的限制。一旦flag
被设置为true
,后续的位可以自由设置以最大化 XOR 值。
3.逐位处理:
for(int i = 30; i >= 0; i--){
long a_bit = (a >> i) & 1;
long b_bit = (b >> i) & 1;
// ... (逻辑处理)
}
- 从最高位(第30位,因为
a
和b
的最大值为10^9
,二进制位数不超过30位)逐位向低位处理。 a_bit
:a
在第i
位的值(0或1)。b_bit
:b
在第i
位的值(0或1)。
4.构建 x
的逻辑
- 目标:在每一位尽可能选择与
a
不同的位值(因为不同的位会使 XOR 值的这一位为1
,从而增加总的 XOR 值)。 - 受限条件:选择的
x
必须满足x <= b
。
if(!flag){
long desired_bit = 1 - a_bit;
if(desired_bit < b_bit){
// Set to desired_bit and set flag to true
x |= (desired_bit << i);
flag = true;
}
else if(desired_bit == b_bit){
// Set to desired_bit and continue
x |= (desired_bit << i);
}
else{
// Set to a_bit
x |= (a_bit << i);
}
}
else{
// Once flag is true, set to desired_bit to maximize XOR
long desired_bit = 1 - a_bit;
x |= (desired_bit << i);
}
-
!flag
情况下(尚未偏离b
的限制):- 计算
desired_bit
,即希望x
的这一位与a
的这一位相反(1 - a_bit
)。 - 比较
desired_bit
与b_bit
:- 如果
desired_bit < b_bit
:- 选择
desired_bit
,因为这保证了在此位设置为desired_bit
后,后续位可以自由选择以最大化 XOR 值。 - 设置
flag = true
,表示后续位不再受b
的限制。
- 选择
- 如果
desired_bit == b_bit
:- 选择
desired_bit
,但仍需继续检查后续位是否会导致x > b
。
- 选择
- 如果
desired_bit > b_bit
:- 无法选择
desired_bit
,因为这会使得x
在此位上超过b
。 - 因此,选择
a_bit
,保持x
在此位与a
相同,以尽量接近b
。
- 无法选择
- 如果
- 计算
-
flag
为true
情况下(已经偏离b
的限制):- 后续位不再受
b
的限制,可以自由选择desired_bit
(即与a
相反的位)以最大化 XOR 值。
- 后续位不再受
5.确保 x
不超过 b
:
if(x > b){
x = b;
}
- 在某些情况下,由于位操作的选择,
x
可能会超过b
。 - 通过这一步骤,确保
x
最终不会超过b
。
6.输出结果:
System.out.println(x ^ a);
附完整代码:
import java.util.Scanner;
// 注意类名必须为 Main,不要有任何 package xxx 信息
public class Main {
public static void main(String[] args){
Scanner in = new Scanner(System.in);
long a = in.nextLong();
long b = in.nextLong();
in.close();
long x = 0;
boolean flag = false;
for(int i = 30; i >= 0; i--){
long a_bit = (a >> i) & 1;
long b_bit = (b >> i) & 1;
if(!flag){
long desired_bit = 1 - a_bit;
if(desired_bit < b_bit){
// Set to desired_bit and set flag to true
x |= (desired_bit << i);
flag = true;
}
else if(desired_bit == b_bit){
// Set to desired_bit and continue
x |= (desired_bit << i);
}
else{
// Set to a_bit
x |= (a_bit << i);
}
}
else{
// Once flag is true, set to desired_bit to maximize XOR
long desired_bit = 1 - a_bit;
x |= (desired_bit << i);
}
}
// Ensure x does not exceed b
if(x > b){
x = b;
}
System.out.println(x ^ a);
}
}