华为OD机试C卷 - 分苹果 - 二进制 - (Java & C++ & JavaScript & Python)

一、题目描述

A、B两个人把苹果分为两堆。

A希望按照他的计算规则等分苹果,他的计算规则是按照二进制加法计算,并且不计算进位12+5=9(1100+0101=9);

B的计算规则是十进制加法,包括正常进位,B希望在满足A的情况下获取苹果重量最多。

输入苹果的数量和每个苹果重量,输出满足A的情况下B获取的苹果总重量。

如果无法满足A的要求,输出-1。

数据范围:

1<=总苹果数量<=20000

1<=每个苹果重量<=10000

二、输入描述

输入第一行是苹果数量:3

输入第二行是每个苹果重量:3 5 6

三、输出描述

输出第一行是B获取的苹果总重量:11

四、测试用例

用例1
输入

4

2 2 2 2

输出

6

说明

总苹果重量:2 + 2 + 2 + 2 = 8

二进制异或总和:2 ^ 2 ^ 2 ^ 2 = 0

最小苹果重量:2

B获取的苹果总重量:8 - 2 = 6

用例2
输入

3

1 2 3

输出

5

说明

总苹果重量:1 + 2 + 3 = 6

二进制异或总和:1 ^ 2 ^ 3 = 0

最小苹果重量:1

B获取的苹果总重量:6 - 1 = 5

五、解题思路

  1. A 的"不进位加法"即异或运算
  2. 要使两堆异或值相等,必须满足:所有苹果的总异或为 0 ,否则无法划分 ⇒ 输出 -1
  3. 当总异或为 0 时,可以把任意一个苹果单独分给 A,其余给 B,都能满足 A 的条件
  4. 为了让 B 拿得最多,应让 A 拿最轻的那个苹果
  5. 因此 B 的最大重量为:总重量 - 最小苹果重量

六、Java源码实现

java 复制代码
public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int count = sc.nextInt();
        // 异或和
        int aWeight = 0;
        // 十进制和
        int sumWeight = 0;
        // 最小重量
        int minWeight = Integer.MAX_VALUE;
        for (int i = 0; i < count; i++) {
            int weight = sc.nextInt();
            // 找到最小重量
            if (weight < minWeight) {
                minWeight = weight;
            }
            sumWeight += weight;
            aWeight ^= weight;
        }
        if (aWeight != 0) {
            System.out.println(-1);
            return;
        }
        // B要获取最大重量,就用总重量-最小重量
        System.out.println(sumWeight - minWeight);
    }
运行结果

七、C++源码实现

cpp 复制代码
#include <iostream>
#include <climits>  // 用于 INT_MAX
using namespace std;

int main() {
    // 读取苹果的总数量
    int n;
    cin >> n;

    // 初始化变量
    long long sumWeight = 0;      // 所有苹果的总重量(使用 long long 防止大数溢出)
    int xorSum = 0;               // A 的"不进位加法"总和,即所有重量的异或结果
    int minWeight = INT_MAX;      // 记录最轻的苹果重量,初始设为整型最大值

    // 循环读取每个苹果的重量
    for (int i = 0; i < n; ++i) {
        int weight;
        cin >> weight;  // 输入当前苹果的重量

        // 累加到总重量(B 的十进制计算方式)
        sumWeight += weight;

        // 计算异或和(A 的不进位二进制加法)
        xorSum ^= weight;

        // 更新最小重量
        if (weight < minWeight) {
            minWeight = weight;
        }
    }

    // 判断是否能满足 A 的"等分"要求
    // A 要求两堆苹果的异或值相等
    // 数学推导:只有当所有苹果的总异或为 0 时,才可能分成两堆异或相等
    if (xorSum != 0) {
        // 无法满足 A 的条件,输出 -1
        cout << -1 << endl;
    } else {
        // 满足 A 的条件
        // 此时,可以把最轻的苹果单独分给 A,其余全给 B
        // 这样 B 拿到的重量最大,为:总重量 - 最小重量
        cout << (sumWeight - minWeight) << endl;
    }

    return 0;  // 程序正常结束
}

八、JavaScript源码实现

javascript 复制代码
function main() {
    const readline = require('readline');

    const rl = readline.createInterface({
        input: process.stdin,
        output: process.stdout
    });

    let lines = [];

    // 监听每行输入
    rl.on('line', (line) => {
        lines.push(line.trim());
    });

    // 输入结束时处理数据
    rl.on('close', () => {
        // 解析输入
        const n = parseInt(lines[0], 10); // 苹果数量
        const weights = lines[1].split(' ').map(Number); // 苹果重量数组

        // 初始化变量
        let sumWeight = 0;           // 总重量(十进制和)
        let xorSum = 0;              // 异或和(A 的不进位加法)
        let minWeight = Infinity;    // 最小苹果重量

        // 遍历所有苹果
        for (let i = 0; i < n; i++) {
            const weight = weights[i];

            sumWeight += weight;     // 累加总重量
            xorSum ^= weight;        // 计算异或和
            if (weight < minWeight) {
                minWeight = weight;  // 更新最小重量
            }
        }

        // 判断是否满足 A 的条件
        if (xorSum !== 0) {
            console.log(-1); // 无法等分
        } else {
            // B 能获得的最大重量:总重 - 最轻的一个
            console.log(sumWeight - minWeight);
        }
    });
}


main();

九、Python源码实现

python 复制代码
import sys

def main():
    """
    主函数:解决 A 和 B 分苹果问题
    A 的规则:二进制不进位加法(即异或)
    B 的目标:在满足 A 的前提下,拿到最多的苹果重量
    """
    # 读取苹果数量
    n = int(input().strip())
    
    # 读取每个苹果的重量
    weights = list(map(int, input().split()))
    
    # 初始化变量
    total_sum = 0          # 十进制总重量(B 的计算方式)
    xor_sum = 0            # 异或总和(A 的不进位加法)
    min_weight = float('inf')  # 最小苹果重量,初始化为正无穷

    # 遍历每个苹果
    for weight in weights:
        total_sum += weight      # 累加总重量
        xor_sum ^= weight        # 计算异或和(A 的规则)
        if weight < min_weight:
            min_weight = weight  # 更新最小重量

    # 判断是否能满足 A 的"等分"要求
    # 只有当所有苹果的异或和为 0 时,才能分成两堆使得 A 认为相等
    if xor_sum != 0:
        # 无法满足 A 的条件
        print(-1)
    else:
        # 满足 A 的条件
        # B 想让自己拿到的重量最多,应让 A 拿最轻的那个苹果
        # B 获得的最大重量 = 总重量 - 最小重量
        print(total_sum - min_weight)


# 调用 main 函数启动程序
if __name__ == "__main__":
    main()
相关推荐
爱和冰阔落2 小时前
【C++ STL栈和队列下】deque(双端队列) 优先级队列的模拟实现与仿函数的介绍
开发语言·数据结构·c++·算法·广度优先
少陵野小Tommy2 小时前
C语言验证哥德巴赫猜想
c语言·开发语言·学习·算法
想唱rap2 小时前
C++类和对象(2)
开发语言·c++·笔记·算法·新浪微博
fwerfv3453454 小时前
C++中的装饰器模式变体
开发语言·c++·算法
Asmalin4 小时前
【代码随想录day 35】 力扣 416. 分割等和子集
算法·leetcode·职场和发展
不枯石8 小时前
Matlab通过GUI实现点云的随机一致性(RANSAC)配准
开发语言·图像处理·算法·计算机视觉·matlab
WWZZ20259 小时前
ORB_SLAM2原理及代码解析:Tracking::CreateInitialMapMonocular() 函数
人工智能·opencv·算法·计算机视觉·机器人·slam·感知
WWZZ20259 小时前
ORB_SLAM2原理及代码解析:Tracking::MonocularInitialization() 函数
人工智能·opencv·算法·计算机视觉·机器人·感知·单目相机