华为OD机考算法题:篮球比赛

news2024/9/30 3:30:05

目录

题目部分

解读与分析

代码实现


题目部分

题目篮球比赛
难度
题目说明篮球(5V5)比赛中,每个球员拥有一个战斗力,每个队伍的所有球员战斗力之和为该队伍的总体战斗力。现有 10 个球员准备分为两队进行训练赛,教练希望 2 个队伍的战斗力差值能够尽可能的小,以达到最佳训练效果。给出 10 个球员的战斗力,如果你是教练,你该如何分队,才能达到最佳训练效果?请说出该分队方案下的最小战斗力差值。
输入描述10 个篮球队员的战斗力(整数,范围[1,10000])战斗力之间用空格分隔,如:10 9 8 7 6 5 4 3 2 1。
不需要考虑异常输入的场景。
输出描述输出描述最小的战斗力差值,如:1。
补充说明
------------------------------------------------------
示例
示例1
输入10 9 8 7 6 5 4 3 2 1
输出1
说明1、2、5、9、10 分为一队,3、4、6、7、8分为一队,两队战斗力之差最小,输出差值1。备注:球员分队方案不唯一,但最小战斗力差值固定是1。


解读与分析

题目解读

10 个数字分成两组,每组 5 个数字,使两组数字之和的差值最小。请输出最小差值。 

分析与思路

本题与《华为OD机考算法题:MVP争夺战》类似,都是把数字分组,要求分组后的数字达到某种要求。不同的是,在《MVP争夺战》中,每组的数字个数是不定的,而在本题中,每组数字的个数是固定的,都是 5。相对而言,本题的思路和实现更简单。

从 10 个数中,穷尽所有的情况,每种情况计算一下两队的差值,找出差值最小的那个。

假设这两组分别为 A 组和 B 组,这 10 个数字分别为 T_{1}T_{2}……T_{10}
我们穷尽的顺序是,先把 T_{1} 放到 A 组,然后基于剩下的 9 个数字,采用相同的方法,穷尽 9 个数字取 4 个的所有可能情况。这样从 10 个数字中取 5 个的情况就降维成了 9 个数字取 4 个,同样的方法,最后可以降为成 6 个数字里取 1 个。
以上是 T_{1}  放到 A 组的情况,接下来就是 T_{2} 放到 A 组,然后从 T_{3} 到 T_{10} 这 8 个数字中,穷尽 8 个数字 取 4 个数字的所有可能情况。

每遍历一种情况,计算两组的数字之差(设为 diff)时,如果 diff 比之前遍历时计算的最小差(设为minDiff)更小,那么更新 minDiff 的值。遍历完所有情况后,最终求得的 minDiff 值即为题目所要求的输出。这种算法遍历的次数为 C_{10}^{5}

在以上的遍历算法中,存在重复计算的情况。题目只关心两组的差值,所以在任意一种组合,把 A 组的数字和 B 组的数字交换,可以看做是同一种情况。如 T_{1}T_{2}T_{3}T_{4}T_{5} 放到 A 组 与 T_{6}T_{7}T_{8}T_{9}T_{10} 放到 A 组其实是等同的。为了减少重复,我们可以假设 A 组的数字之和小于或等于 B 组的数字之和,即 A 组数字之和小于或等于所有数字之和(设为 sum)的一半。那么在穷举所有情况时,发现 A 组数字之和已经超过 (sum/2),那么就可以忽略这种组合了。这样可以减少一半遍历,遍历次数变为 \frac{C_{10}^{5}}{2}

既然需要保证A组数字之和小于或等于 (sum/2),我们可以先对数字进行从小到大排序,进一步减少遍历次数。

综上,此算法的遍历次数不超过 \frac{C_{10}^{5}}{2}。下面,我们计算一下最大遍历次数。

由组合计算公式 C_{m}^{n} = \frac{m!}{n!(m-n)!},可以得出  \frac{C_{10}^{5}}{2} = \frac{ 10!}{(5!)(5!)*2} = 126,最多不超过 126 次。


代码实现

Java代码

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

/**
 * 篮球比赛
 * @since 2023.09.15
 * @version 0.1
 * @author Frank
 *
 */
public class BasketballGame {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		while (sc.hasNext()) {
			String input = sc.nextLine();
			String[] strNumbers = input.split( " " );
			// 此处 count == numbers.count,可以完全不用考虑 count.
			processBasketballGame( strNumbers );
		}
	}
	
	private static void processBasketballGame( String strNumbers[] )
	{
		Integer[] numbers = new Integer[strNumbers.length];
		int sum = 0;
		for( int i = 0; i < numbers.length; i ++ )
		{
			numbers[i] = Integer.parseInt( strNumbers[i] );
			sum += numbers[i];
		}
		
		Arrays.sort( numbers );
		int minDiff = sum;	// minDiff 一定小于 sum
 		
		List<Integer> numList = new ArrayList<Integer>( Arrays.asList( numbers ) );
		
		minDiff = getMinDiff( sum, minDiff, 0, 0, numList );
		System.out.println( minDiff );
	}

	
	private static int getMinDiff( int SUM, int minDiff, int currentSum, int currentCnt, List<Integer> numbers )
	{			
		if( currentCnt + numbers.size() < 5 )
		{
			return SUM;
		}
		
		List<Integer> tmpRemovedNumber = new ArrayList<Integer>(); 
		
		for( int i = 0; i < numbers.size(); i ++ )
		{
			int tmpMinDiff = SUM;
			int tmpNumber = numbers.get( i );
			
			int tmpCurrentSum = currentSum + tmpNumber;
			int tmpCurrentCnt = currentCnt + 1;
			
			if( tmpCurrentSum * 2 > SUM )
			{
				break; // 可以break,因为后面的数字更大。
			}
				
			if( tmpCurrentCnt == 5 )
			{
				tmpMinDiff = SUM - tmpCurrentSum * 2;
				if( tmpMinDiff < minDiff )
				{
					minDiff = tmpMinDiff;
					continue;
				}
			}
			
			tmpRemovedNumber.add( tmpNumber );
			numbers.remove( i );
			tmpMinDiff = getMinDiff( SUM, minDiff, tmpCurrentSum, tmpCurrentCnt, numbers );
			if( tmpMinDiff < minDiff )
			{
				minDiff = tmpMinDiff;
			}
//			numbers.add( i, tmpNumber );  // 不必加回去,可以减少一半的穷举数
		}		
		
		for( int i = 0; i < tmpRemovedNumber.size(); i ++ )
		{
			numbers.add( i, tmpRemovedNumber.get( i ) );
		}
		return minDiff;
	}
	
}

JavaScript代码

const rl = require("readline").createInterface({ input: process.stdin });
var iter = rl[Symbol.asyncIterator]();
const readline = async () => (await iter.next()).value;
void async function() {
    while (line = await readline()) {
        // count 可以忽略
        var strNumbers = line.split(" ");
        processBasketballGame(strNumbers);
    }
}();

function processBasketballGame(strNumbers) {
    var numbers = new Array();
    var sum = 0;
    for (var i = 0; i < strNumbers.length; i++) {
        numbers[i] = parseInt(strNumbers[i]);
        sum += numbers[i];
    }

    numbers.sort();
    var minDiff = sum; // minDiff 一定小于 sum

    minDiff = getMinDiff(sum, minDiff, 0, 0, numbers);
    console.log(minDiff);
}

function getMinDiff(SUM, minDiff, currentSum, currentCnt, numbers) {
    if (currentCnt + numbers.length < 5) {
        return SUM;
    }

    var tmpRemovedNumber = new Array();

    for (var i = 0; i < numbers.length; i++) {
        var tmpMinDiff = SUM;
        var tmpNumber = numbers[i];

        var tmpCurrentSum = currentSum + tmpNumber;
        var tmpCurrentCnt = currentCnt + 1;

        if (tmpCurrentSum * 2 > SUM) {
            break; // 可以break,因为后面的数字更大。
        }

        if (tmpCurrentCnt == 5) {
            tmpMinDiff = SUM - tmpCurrentSum * 2;
            if (tmpMinDiff < minDiff) {
                minDiff = tmpMinDiff;
                continue;
            }
        }

        tmpRemovedNumber.push(tmpNumber);
        numbers.splice(i, 1);
        tmpMinDiff = getMinDiff(SUM, minDiff, tmpCurrentSum, tmpCurrentCnt, numbers);
        if (tmpMinDiff < minDiff) {
            minDiff = tmpMinDiff;
        }
    }

    for (var i = 0; i < tmpRemovedNumber.length; i++) {
        numbers.splice(i, 0, tmpRemovedNumber[i]);
    }
    return minDiff;
}

(完)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1025471.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

深度学习——卷积神经网络

卷积神经网络 1 计算机视觉 (Computer Vision)2 边缘检测示例 (Edge Detection Example)3 更多边缘检测内容 (More Edge Detection Example)4 Padding5 卷积步长 (Strided Convolutions)6 三维卷积 (Convolutions Over Volumes)7 单层卷积网络 (One Layer of a Convolutional N…

从速度到兼容性:一起来看看腾讯文档双核引擎的全面优势

文章目录 前言功能测评打开编辑本地文件本地文件云存储转多人在线编辑便捷的文件分享 测评感受 前言 在刚结束的腾讯数字生态大会上&#xff0c;腾讯文档发布了独家自主研发的双核编辑引擎。根据会上介绍&#xff0c;该引擎采用了统一的 OOXML 底层存储格式&#xff0c;实现了…

echarts-可视化地图防重叠文本框

我在第一篇可视化地图中&#xff0c;有一些基础介绍&#xff0c;本篇文章就是多展示一些效果&#xff0c;大家可以按需获取。 先直接上效果图 这里的配置项有用到 1、通过geo展示多层地图&#xff0c;这样可以像上图所示&#xff0c;通过错位有了一些3D效果&#xff1b; 2、北…

golang实现远程控制主机

文章目录 ssh原理使用golang远程下发命令使用golang远程传输文件 ssh原理 说到ssh原理个人觉得解释最全的一张图是这张华为画的 Connection establishment 这一步就是建立tcp连接 version negotiation 这一步是ssh客户端(连接者)和被ssh服务端(连接者)进行协议的交换&#xf…

湖南长沙石雕石质文物三维扫描数字化雕刻3D打印复刻文化遗产-CASAIM中科广电

石质文物主要包括石雕、石塔和古建筑等&#xff0c;颇具代表性的雕刻动物作品有&#xff1a;龙、凤、狮子、麒麟、貔貅、金蟾等。石雕是我国文化遗产的重要组成&#xff0c;在书写灿烂文明中扮演着重要角色&#xff0c;记载了我国文化和历史的变迁。 随着现代艺术的发展&#…

vscode快捷键大全中英文

vscode快捷键大全中英文 源文件下载链接

700多心理测试性格测试大全ACCESS\EXCEL数据库

这是一个关于心理测试、性格测试的ACCESS数据库&#xff0c;这个测试有一个测试项目一个问题选择后就有结果&#xff0c;也有一个测试项目有N多题需做完N多题根据各题得分得出总结果&#xff0c;所以ACCESS数据表的结构设计的很灵活。 测试项目表&#xff1a;为整个ACCESS数据…

DDoS攻击和CC攻击

DDoS是&#xff08;Distributed Denial of Service&#xff0c;分布式拒绝服务&#xff09;攻击和CC&#xff08;Challenge Collapsar&#xff0c;挑战黑洞) 攻击是两种常见且具有破坏性的攻击类型&#xff0c;它们可以对网络基础设施和在线业务造成重大损害。为了抵御这些攻击…

vscode编写前端提升效率的三个必不可缺的插件以及使用方法

直接官网下载这个软件就行&#xff0c;没什么操作的。 这里面有新建文件夹&#xff0c;你可以自己去建一个文件夹 然后点击那个小号&#xff0c;就可以新建一个文件&#xff0c;比如说demo01.html,⚠️后面的html是你需要自己手动输入的 第一个插件&#xff0c;就是这个她可以让…

Android 虚拟机

文章目录 Android 虚拟机Java虚拟机基于栈的虚拟机栈的执行流程 Dalvik虚拟机基于寄存器的虚拟机寄存器的执行流程Java虚拟机与Dalvik虚拟机区别 ART虚拟机Android 7.0的运行方式 Android 虚拟机 Java虚拟机 基于栈的虚拟机 每一个运行时的线程&#xff0c;都有一个独立的栈…

包装类型和基本类型的转换(自动装箱/自动拆箱)

①包装类型->基本类型 ②基本类型->包装类型 //第一种&#xff1a;直接创建对象Integer ynew Integer(20);//第二种&#xff1a;使用Integer类的静态方法valueOf()Integer zInteger.valueOf(30); JAVA对以上内容的简化&#xff1a; 自动装箱&#xff08;基本类型->包…

嵌入式C语言知识复习和提高

文章目录 前言基础知识main函数防BUG注释&#xff08;重要&#xff09;关键字标识符命名&#xff08;驼峰命名&#xff09;常量类型变量printf1.输出不同类型数据2.输出不同宽度数据3.不同类型数据长度归类 scanf函数运算符sizeof&#xff08;运算符&#xff0c;优先级2&#x…

Springboot ruoyi配置mysql备份定时任务

一、RuoYiConfig.class 新增获取备份路径方法 public static String getDataBaseBackUp() {return getProfile() "/dbBackUp";} 二、RyTask&#xff1a;新增备份数据库方法 mySqlDump方法&#xff1a;参数详见代码 package com.ruoyi.quartz.task;import cn.hut…

智慧工地4G+蓝牙+GPS/北斗RTK人员定位系统解决方案

工地是事故多发地&#xff0c;对工地人员进行定位管理非常有必要。传统工地管理手段存在局限性&#xff0c;往往难以高效地管理工地上的人员。随着科技的发展&#xff0c;工地人员定位管理系统逐渐普及。通过使用人员定位系统&#xff0c;工地管理者可以对工地上的人员进行全面…

对权限的理解和使用

目录 一&#xff1a;用户权限&#xff1a; ★su命令 ★sudo命令 二&#xff1a;文件权限 ★文件的类型权限 ★文件夹的权限的使用 ▲文件夹的可读权限&#xff1a; ▲文件夹的可写权限&#xff1a; ▲文件夹的可执行权限&#xff1a; ★权限的修改操作 ▲chmod命令 ★对于文件的…

C++:deque的概念以及stack和queue的模拟实现

文章目录 stack的模拟实现dequequeue的模拟实现 本篇主要总结的是stack和queue的模拟实现以及deque的原理 stack的模拟实现 和前面的模拟实现相同&#xff0c;首先要看官方实现的功能 这里引入了Container的概念&#xff0c;从字面意思来看&#xff0c;也就是说&#xff0c;在…

pdf转换成word,这里有几个不错的方法

pdf转换成word怎么转&#xff1f;大家都知道&#xff0c;在电脑进行各种文件格式转换中&#xff0c;PDF转换为Word文档的需求量应该是最大的。在我们的日常工作中&#xff0c;经常需要将PDF转换为Word格式。为什么要将pdf文件转换成word&#xff0c;相信大家也都应该知道的&…

图解 | 这就是网络

你是一台电脑&#xff0c;你的名字叫 A 很久很久之前&#xff0c;你不与任何其他电脑相连接&#xff0c;孤苦伶仃。 直到有一天&#xff0c;你希望与另一台电脑 B 建立通信&#xff0c;于是你们各开了一个网口&#xff0c;用一根网线连接了起来。 用一根网线连接起来怎么就能&q…

二叉树链式结构基础

一、前中后序遍历 1、前序遍历&#xff1a;前序遍历是采用 根 - 左子树 - 右子树 的顺序遍历二叉树。 也就是把整棵树分为一个个子问题&#xff0c;每个结点都可以看作 根、左子树、右子树 三个部分 (左右子树可以为空&#xff0c;就是单节点&#xff0c;根为空就表示探索完成&…

自动化测试需知的4项测试工具!

一般来说学自动化会建议大家先学selenium&#xff0c;因为最早的时候&#xff0c;自动化就代表selenium&#xff0c;进入测试行业就开始做接口测试&#xff0c;而且现在基本每个公司都需要接口测试。今天就和大家聊一下接口测试的工具。 一、Robot Framework 机器人框架。之所…