机考E卷100分题 - 分苹果

题目描述

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

输入

3
3 5 6
12

输出

11
1

说明

示例2

输入

8
7258 6579 2602 6716 3050 3564 5396 1773
12

输出

35165
1

说明

解题思路

这道题目要求你在给定的条件下计算A和B两个人分苹果的结果。A的要求是按照二进制加法(不进位)等分苹果,而B希望在满足A的要求下获取苹果总重量的最大值。如果无法满足A的要求,则输出-1。

题目分析

  1. 二进制加法不进位

    • 二进制加法不进位的意思是直接对每一位进行相加,但不进行进位处理。
    • 比如:12(1100)和5(0101)相加的结果是9(1001),因为在二进制表示中:
      • 1+0 = 1
      • 1+1 = 0(不进位)
      • 0+0 = 0
      • 0+1 = 1
  2. 题目要求

    • 你需要找到一个办法,把苹果分成两堆,使得两堆苹果的总重量按二进制加法(不进位)结果相等。
    • 在满足这个条件的前提下,让B获取的苹果总重量最大。

示例分析

示例 1

  • 输入:

    3
    3 5 6
    12
    
  • 分析:

    • 可能的分法有:
      • 3, 5 | 6
      • 3, 6 | 5
      • 5, 6 | 3
    • 根据二进制加法规则(不进位),3 + 5 = 6,3 + 6 = 5,5 + 6 = 3。
    • 通过手动验证,发现其中一堆可以是{5, 6},另一堆是{3},此时B获取的总重量最大为11。

示例 2:

8
7258 6579 2602 6716 3050 3564 5396 1773
12
  1. 计算总异或和:
    首先计算所有苹果重量的异或和。如果总异或和不为 0,那么就不可能按照 A 的规则将苹果分成两堆,此时输出 -1
    XOR sum = 7258 ⊕ 6579 ⊕ 2602 ⊕ 6716 ⊕ 3050 ⊕ 3564 ⊕ 5396 ⊕ 1773 \text{XOR sum} = 7258 \oplus 6579 \oplus 2602 \oplus 6716 \oplus 3050 \oplus 3564 \oplus 5396 \oplus 1773 XOR sum=7258⊕6579⊕2602⊕6716⊕3050⊕3564⊕5396⊕1773

    通过逐个异或,可以计算出:

    XOR sum = 0 \text{XOR sum} = 0 XOR sum=0

    因为总异或和为 0,所以有可能按照 A 的规则分堆。

  2. 找出 B 的最大重量:
    因为 XOR 总和为 0,我们可以找到一种分法,使得两个堆的异或结果为 0。我们将总重量计算出来:

    Total Sum = 7258 + 6579 + 2602 + 6716 + 3050 + 3564 + 5396 + 1773 = 36838 \text{Total Sum} = 7258 + 6579 + 2602 + 6716 + 3050 + 3564 + 5396 + 1773 = 36838 Total Sum=7258+6579+2602+6716+3050+3564+5396+1773=36838
    然后我们考虑两堆的分配,使得其中一个堆的重量最大。因为总异或和为 0,我们可以选择总重量中最小的那个数,从总和中减去,这样可以最大化 B 的重量:

    Minimum Weight = min ⁡ ( 7258 , 6579 , 2602 , 6716 , 3050 , 3564 , 5396 , 1773 ) = 1773 \text{Minimum Weight} = \min(7258, 6579, 2602, 6716, 3050, 3564, 5396, 1773) = 1773 Minimum Weight=min(7258,6579,2602,6716,3050,3564,5396,1773)=1773

    因此,B 可以获得的最大重量是:

    Max Weight for B = Total Sum − Minimum Weight = 36838 − 1773 = 35165 \text{Max Weight for B} = \text{Total Sum} - \text{Minimum Weight} = 36838 - 1773 = 35165 Max Weight for B=Total Sum−Minimum Weight=36838−1773=35165

  3. 输出结果:

最终,输出 B 可以获取的最大苹果重量:

35165
1

结论

  • 如果总异或和为 0,找到最小的重量,将其分给 A,B 的最大重量是总和减去这个最小重量。
  • 如果总异或和不为 0,则输出 -1

Java

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        // 创建一个扫描器对象,用于读取输入
        Scanner scanner = new Scanner(System.in);
        // 读取苹果的数量 n
        int n = scanner.nextInt();
        // 创建一个大小为 n 的数组,用于存储每个苹果的重量
        int[] a = new int[n];
        // 循环读取每个苹果的重量,并存储到数组中
        for (int i = 0; i < n; i++) {
            a[i] = scanner.nextInt();
        }
        // 初始化异或总和变量
        int sums = 0;
        // 初始化最小值变量为整型的最大值
        int min = Integer.MAX_VALUE;
        // 遍历所有苹果的重量
        for (int x : a) {
            // 按位异或操作,更新异或总和
            sums = sums ^ x;
            // 找到当前最小的苹果重量
            if (x < min) {
                min = x;
            }
        }
        // 如果异或总和不为 0,则无法按 A 的规则分堆,输出 -1
        if (sums != 0) {
            System.out.println(-1);
        } else {
            // 计算所有苹果重量的总和
            int sum = 0;
            for (int x : a) {
                sum += x;
            }
            // 输出 B 可以获取的最大苹果重量(总和减去最小的苹果重量)
            System.out.println(sum - min);
        }
    }
}
1234567891011121314151617181920212223242526272829303132333435363738394041

Python

import sys

# 读取苹果的数量 n
n = int(input())
# 读取每个苹果的重量并存储到列表 a 中
a = list(map(int, input().split()))

# 初始化异或总和
sums = 0
# 初始化最小值为系统的最大整数
min_val = sys.maxsize
# 遍历所有苹果的重量
for x in a:
    # 按位异或操作,更新异或总和
    sums = sums ^ x
    # 找到当前最小的苹果重量
    if x < min_val:
        min_val = x

# 如果异或总和不为 0,则无法按 A 的规则分堆,输出 -1
if sums != 0:
    print(-1)
else:
    # 计算所有苹果重量的总和
    total_sum = sum(a)
    # 输出 B 可以获取的最大苹果重量(总和减去最小的苹果重量)
    print(total_sum - min_val)
123456789101112131415161718192021222324252627

JavaScript

const readline = require('readline');

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

let n;  // 苹果数量
let a;  // 每个苹果的重量数组

// 读取输入的第一行,苹果数量 n
rl.on('line', (inputN) => {
  n = parseInt(inputN);
  
  // 读取输入的第二行,苹果的重量列表
  rl.on('line', (inputA) => {
    a = inputA.split(' ').map(Number);
    
    // 初始化异或总和
    let sums = 0;
    // 初始化最小值为 JavaScript 中安全的最大整数
    let min_val = Number.MAX_SAFE_INTEGER;
    
    // 遍历所有苹果的重量
    a.forEach((x) => {
      // 按位异或操作,更新异或总和
      sums = sums ^ x;
      // 找到当前最小的苹果重量
      if (x < min_val) {
        min_val = x;
      }
    });
    
    // 如果异或总和不为 0,则无法按 A 的规则分堆,输出 -1
    if (sums !== 0) {
      console.log(-1);
    } else {
      // 计算所有苹果重量的总和
      const total_sum = a.reduce((sum, x) => sum + x, 0);
      // 输出 B 可以获取的最大苹果重量(总和减去最小的苹果重量)
      console.log(total_sum - min_val);
    }
    
    rl.close();  // 关闭读取接口
  });
});
12345678910111213141516171819202122232425262728293031323334353637383940414243444546

C++

#include <iostream>
#include <vector>
#include <limits>

int main() {
    int n;
    // 读取苹果的数量 n
    std::cin >> n;
    // 创建一个大小为 n 的向量,用于存储每个苹果的重量
    std::vector<int> a(n);
    // 循环读取每个苹果的重量,并存储到向量中
    for (int i = 0; i < n; i++) {
        std::cin >> a[i];
    }
    // 初始化异或总和变量
    int sums = 0;
    // 初始化最小值变量为整型的最大值
    int min = std::numeric_limits<int>::max();
    // 遍历所有苹果的重量
    for (int x : a) {
        // 按位异或操作,更新异或总和
        sums = sums ^ x;
        // 找到当前最小的苹果重量
        if (x < min) {
            min = x;
        }
    }
    // 如果异或总和不为 0,则无法按 A 的规则分堆,输出 -1
    if (sums != 0) {
        std::cout << -1 << std::endl;
    } else {
        // 计算所有苹果重量的总和
        int sum = 0;
        for (int x : a) {
            sum += x;
        }
        // 输出 B 可以获取的最大苹果重量(总和减去最小的苹果重量)
        std::cout << sum - min << std::endl;
    }
    return 0;
}
1234567891011121314151617181920212223242526272829303132333435363738394041

C语言

#include <stdio.h>
#include <limits.h>  // 用于定义整型的最大值 INT_MAX

int main() {
    int n;
    // 读取苹果的数量 n
    scanf("%d", &n);
    
    // 创建一个大小为 n 的数组,用于存储每个苹果的重量
    int a[n];
    
    // 循环读取每个苹果的重量,并存储到数组中
    for (int i = 0; i < n; i++) {
        scanf("%d", &a[i]);
    }
    
    // 初始化异或总和变量
    int sums = 0;
    // 初始化最小值变量为整型的最大值
    int min = INT_MAX;
    
    // 遍历所有苹果的重量
    for (int i = 0; i < n; i++) {
        // 按位异或操作,更新异或总和
        sums = sums ^ a[i];
        // 找到当前最小的苹果重量
        if (a[i] < min) {
            min = a[i];
        }
    }
    
    // 如果异或总和不为 0,则无法按 A 的规则分堆,输出 -1
    if (sums != 0) {
        printf("-1\n");
    } else {
        // 计算所有苹果重量的总和
        int sum = 0;
        for (int i = 0; i < n; i++) {
            sum += a[i];
        }
        // 输出 B 可以获取的最大苹果重量(总和减去最小的苹果重量)
        printf("%d\n", sum - min);
    }
    
    return 0;
}
12345678910111213141516171819202122232425262728293031323334353637383940414243444546
#牛客创作赏金赛#

主要记录自己的刷题日常,学而时习之。

全部评论

相关推荐

1 收藏 评论
分享
牛客网
牛客企业服务