编程题:求最大异或值

问题描述:

给定两个正整数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 从标准输入读取两个正整数 ab
  • 关闭 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位,因为 ab 的最大值为 10^9,二进制位数不超过30位)逐位向低位处理。
  • a_bita 在第 i 位的值(0或1)。
  • b_bitb 在第 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_bitb_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
  • flagtrue 情况下(已经偏离 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);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值