Bootstrap

【华为OD-E卷 -58 分苹果 100分(python、java、c++、js、c)】

【华为OD-E卷 - 分苹果 100分(python、java、c++、js、c)】

题目

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

用例

用例一:
输入:
3
3 5 6
输出:
11
用例二:
输入:
8
7258 6579 2602 6716 3050 3564 5396 1773
输出:
35165

python解法

  • 解题思路:
  • 这段代码的目标是处理一组权重,判断是否能将其分成两个非空子集,使得两个子集的按位异或结果相等。如果可以,将两个子集的总和的最大值作为结果输出;如果不能,返回 -1。

核心思想是:

如果所有权重的异或值(xor_result)为 0,说明可以通过某种划分使两个子集的异或值相等。
若可以划分,去掉最小的权重值后,剩余权重的总和即为最大的子集总和。
如果异或值不为 0,说明无法划分,返回 -1。

# 输入权重的数量
n = int(input())

# 输入权重列表
weights = list(map(int, input().split()))

# 计算最大子集权重总和
def find_max_weight(weights):
    # 对权重进行升序排序
    sorted_weights = sorted(weights)

    # 初始化异或结果和总和
    xor_result = 0  # 存储所有权重的异或值
    total = 0       # 存储所有权重的总和

    # 遍历权重,计算异或值和总和
    for weight in sorted_weights:
        xor_result ^= weight  # 累积异或值
        total += weight       # 累积总和

    # 如果异或值为 0,说明可以划分为两个异或值相等的子集
    if xor_result == 0:
        return total - sorted_weights[0]  # 最大子集总和为总和减去最小值
    else:
        return -1  # 如果异或值不为 0,无法划分

# 调用函数并输出结果
print(find_max_weight(weights))

java解法

  • 解题思路
  • 这段代码的目标是判断一组权重是否可以分成两个非空子集,使得两个子集的按位异或结果相等。如果可以,则返回两个子集总和的最大值;如果不能,则返回 -1。

核心思想
异或的性质:

如果一组数字的异或值为 0,说明可以划分为两个异或结果相等的子集。
异或运算满足交换律和结合律,因此排列顺序不影响结果。
最大子集总和计算:

如果异或值为 0,将权重总和减去最小值,得到最大子集总和。
如果异或值不为 0,说明无法划分,返回 -1。
排序的作用:

排序便于直接找到最小值,简化后续计算

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);

        // 输入权重的数量
        int size = input.nextInt();
        int[] weights = new int[size];
        
        // 输入权重列表
        for (int i = 0; i < size; i++) {
            weights[i] = input.nextInt();
        }

        // 调用方法计算结果并输出
        System.out.println(findMaxWeight(size, weights));
    }

    /**
     * 计算最大子集总和或判断是否无法划分
     *
     * @param size    权重数组的大小
     * @param weights 权重数组
     * @return        最大子集总和或 -1
     */
    public static int findMaxWeight(int size, int[] weights) {
        // 对权重数组进行升序排序
        Arrays.sort(weights);

        // 初始化最小值、异或值和总权重
        int minVal = weights[0];   // 最小值为排序后数组的第一个元素
        int xorVal = minVal;       // 初始异或值为最小值
        int totalWeight = minVal;  // 初始总权重为最小值

        // 遍历剩余的权重,计算异或值和总权重
        for (int i = 1; i < size; i++) {
            xorVal ^= weights[i];       // 累积异或值
            totalWeight += weights[i]; // 累积总权重
        }

        // 判断异或值是否为 0
        return xorVal == 0 ? totalWeight - minVal : -1;
    }
}

C++解法

  • 解题思路
更新中

C解法

  • 解题思路

更新中

JS解法

  • 解题思路

  • 这段代码的目标是根据输入的一组权重,判断是否可以将它们划分为两个非空子集,使得两个子集的按位异或结果相等。如果可以划分,则返回两个子集总和的最大值;如果无法划分,则返回 -1。

核心思想
异或运算的性质:

异或运算满足交换律和结合律。
如果一组数字的异或值为 0,则说明可以划分为两个异或值相等的子集。
总和计算:

如果可以划分,总和的最大值是所有权重的总和减去最小值(即,将最小值分配到一个子集,其余权重分配到另一个子集)。
如果不能划分,直接返回 -1

const readline = require("readline");

// 创建 readline 接口,用于读取标准输入
const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout,
});

// 存储输入的行
const lines = [];

// 每次读取一行时触发
rl.on("line", (line) => {
    lines.push(line);

    if (lines.length === 2) { // 当输入的行数达到两行时,开始处理
        const n = parseInt(lines[0]); // 第 1 行:权重数量
        const weights = lines[1].split(" ").map(Number); // 第 2 行:权重数组

        console.log(computeWeights(n, weights)); // 调用主逻辑函数并输出结果

        lines.length = 0; // 清空存储的行,准备接收下一组输入
    }
});

/**
 * 计算最大子集总和或判断是否无法划分
 *
 * @param {number} n 权重数量
 * @param {number[]} weights 权重数组
 * @return {number} 最大子集总和或 -1
 */
function computeWeights(n, weights) {
    // 找到最小的权重值
    const minWeight = Math.min(...weights);

    // 初始化异或值和总权重
    let bitwiseSum = 0; // 用于存储所有权重的按位异或值
    let totalSum = 0;   // 用于存储所有权重的总和

    // 遍历权重数组,累积异或值和总和
    for (let weight of weights) {
        bitwiseSum ^= weight;  // 按位异或累积
        totalSum += weight;    // 累积总和
    }

    // 判断异或值是否为 0
    if (bitwiseSum === 0) {
        // 如果异或值为 0,返回最大子集总和(总和减去最小值)
        return totalSum - minWeight;
    } else {
        // 如果异或值不为 0,返回 -1
        return -1;
    }
}

注意:

如果发现代码有用例覆盖不到的情况,欢迎反馈!会在第一时间修正,更新。
解题不易,如对您有帮助,欢迎点赞/收藏