游戏分组 - 华为OD统一考试(C卷)

OD统一考试(C卷)

分值: 100分

题解: Java / Python / C++

alt

题目描述

部门准备举办一场王者荣耀表演赛,有 10 名游戏爱好者参与,分为两队,每队 5 人。

每位参与者都有一个评分,代表着他的游戏水平。为了表演赛尽可能精彩,我们需要把 10 名参赛者分为实力尽量相近的两队。

一队的实力可以表示为这一队 5 名队员的评分总和。

现在给你 10 名参与者的游戏水平评分,请你根据上述要求分队,最后输出这两组的实力差绝对值。

输入描述

10 个整数,表示 10 名参与者的游戏水平评分。范围在 [1,10000] 之间。

输出描述

实力最相近两队的实力差绝对值。

示例1

输入:
1 2 3 4 5 6 7 8 9 10

输出:
1

说明:
10 名队员分为两组,两组实力差绝对值最小为 1

题解

核心是通过递归穷举所有可能的分组情况,计算两组实力之差的绝对值,最终找到实力最相近的两组。这是一种暴力穷举的方法,对于题目中给定的规模,是可行的。

此题的特点:

  • 通过递归穷举分组情况。
  • 利用全局变量记录最小差值。
  • 对每一种分组情况计算实力差值。

Java

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

/**
 * @author code5bug
 */
public class Main {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        List<Integer> list = new ArrayList<>();
        while (scanner.hasNext()) list.add(scanner.nextInt());
        Solution solution = new Solution(list);
        solution.solve(0, 0, 0);
        System.out.println(solution.minDifference);
    }

}

class Solution {
    List<Integer> arr;
    int total, n, minDifference;

    public Solution(List<Integer> arr) {
        this.arr = arr;
        this.n = arr.size();
        this.minDifference = Integer.MAX_VALUE;
        this.total = arr.stream().mapToInt(Integer::intValue).sum();
    }

    public void solve(int idx, int selectCnt, int selectSum) {
        if (selectCnt == n / 2) {
            minDifference = Math.min(minDifference, Math.abs(total - 2 * selectSum));
            return;
        }

        for (int i = idx; i < n; i++) {
            // 不选择时
            solve(i + 1, selectCnt, selectSum);
            // 选择时
            solve(i + 1, selectCnt + 1, selectSum + arr.get(i));
        }
    }
}


Python

from math import inf

arr = list(map(int, input().split()))

# 最小差值, 全部人员总实力, 人员总数
min_difference, tot, n = inf, sum(arr), len(arr)

def solve(idx: int, select_cnt: int, select_sum: int):
    global min_difference
    if select_cnt == n // 2:  # 当全部人员选择了一半时,计算两组实力差值是否更小
        min_difference = min(min_difference, abs(tot - 2 * select_sum))
        return

    for i in range(idx, n):
        # 不选择时
        solve(i + 1, select_cnt, select_sum)
        # 选择时
        solve(i + 1, select_cnt + 1, select_sum + arr[i])


solve(0, 0, 0)

print(min_difference)

C++

#include <bits/stdc++.h>

using namespace std;

int min_difference = INT_MAX;
vector<int> arr;
int tot, n;

void solve(int idx, int select_cnt, int select_sum) {
    if (select_cnt == n / 2) {
        min_difference = min(min_difference, abs(tot - 2 * select_sum));
        return;
    }

    for (int i = idx; i < n; i++) {
        // 不选择时
        solve(i + 1, select_cnt, select_sum);
        // 选择时
        solve(i + 1, select_cnt + 1, select_sum + arr[i]);
    }
}

int main() {
    // 读取输入
    int num;
    while (cin >> num) {
        arr.push_back(num);
    }

    tot = accumulate(arr.begin(), arr.end(), 0);
    n = arr.size();

    solve(0, 0, 0);

    cout << min_difference << endl;

    return 0;
}

🙏整理题解不易, 如果有帮助到您,请给点个赞 ‍❤️‍ 和收藏 ⭐,让更多的人看到。🙏🙏🙏

#面经##秋招##春招##校招##华为#
全部评论

相关推荐

能干的三文鱼刷了100道题:公司可能有弄嵌入式需要会画pcb的需求,而且pcb能快速直观看出一个人某方面的实力。看看是否有面试资格。问你问题也能ai出来,pcb这东西能作假概率不高
点赞 评论 收藏
分享
Cherrycola01:0实习 0项目 约等于啥也没有啊 哥们儿这简历认真的吗
点赞 评论 收藏
分享
评论
6
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务