• 华为OD机考算法题:MVP争夺战


    目录

    题目部分

    解读与分析

    代码实现


    题目部分

    题目MVP争夺战
    难度
    题目说明在星球争霸篮球赛对抗赛中,强大的宇宙战队,希望每个人都能拿到MVP。
    MVP的条件是,单场最高分得分获得者,可以并列,所以宇宙战队决定在比赛中,尽可能让更多的队员上场,且让所有有得分的队员得分都相同。
    然而比赛过程中的每一分钟的得分都只能由某一个人包揽。
    输入描述输入第一行为一个数字t,表示有得分的分钟数( 1 <= t <= 50)。
    第二行为t个数字,代表每一分钟的得分 p(1 <= p <= 50)。
    输出描述输出有得分的队员都是MVP时最少的MVP得分。
    补充说明
    ------------------------------------------------------
    示例
    示例1
    输入9
    5 2 1 5 2 1 5 2 1
    输出6
    说明样例解释:一共4人得分,分别都为6分
    5 + 1
    5 + 1
    5 + 1
    2 + 2 + 2


    解读与分析

    题目解读

    输入一系列数字代表球员的得分,要求把这些分数尽可能分给多的球员,且保证每个球员的得分之和相等。求出当平均分配的人数最多时,这个平均得分是多少。

    换种说法,就是把指定的一组数字分成若干组(分成多少组不确定,每组的数字个数也不固定),使每组数字之和相等。求这个和的最小值。和最小,意味着分成的组数最多。

    题目中给出了 n 个数字,要求把这 n 个数字划分成 m 组,保证 m 组中每组的数字之和相等,即每组的数字之和等于 sun / m(注: sum/m 取整)。

    需要注意:每组的数字个数并不是固定的,可能各不相同。

    分析与思路

    虽然此题难度标识为“易”,但思路和方法却不那么容易。

    我能想到最好的办法是动态规划,尝试把 n 个数字放到不同的组中。假设 n 个数中最大的值为 max,那么组的个数的取值范围是 [ 1, sum / max ]。

    我们采用递归的方式,尝试把某个数字放到一个组中,然后在此前提下,使用递归尝试把剩下的数字放进某一组,以此穷尽所有可能的情形。

    从分组数为 ( sum / max 取整) 开始尝试,如果满足分组条件,此时的分组数就是最大分组数,返回此时每组的数字之和,退出程序。如果不满足,分组数减 1,继续尝试,直至分组数为 1。
    满足分组的条件是:每组的数字之和相等,且所有数字都归属于某一组。

    此题最后一定会有结果。在最坏的情况下,所有的数字都在同一个组。在题目中代表着着,只有一个MVP球员,这个球员包揽了所有的得分。

    此算法用到了递归,会遍历可能的分组数情况。在每一次分组,穷尽所有数字放到各个组,所需的时间复杂度 O( n^{2} ),空间复杂度 O(n)。


    代码实现

    Java代码

    1. import java.util.ArrayList;
    2. import java.util.List;
    3. import java.util.Scanner;
    4. /**
    5. * MVP争夺战
    6. *
    7. * @since 2023.09.11
    8. * @version 0.1
    9. * @author Frank
    10. *
    11. */
    12. public class MVPCompetition {
    13. public static void main(String[] args) {
    14. Scanner sc = new Scanner(System.in);
    15. while (sc.hasNext()) {
    16. String input = sc.nextLine();
    17. int count = Integer.parseInt( input );
    18. input = sc.nextLine();
    19. String[] numbers = input.split( " " );
    20. processMVPCompetition( numbers );
    21. }
    22. }
    23. private static void processMVPCompetition( String numbers[] )
    24. {
    25. int sum = 0;
    26. int maxNum = 0;
    27. List numList = new ArrayList();
    28. for( int i = 0; i < numbers.length; i ++ )
    29. {
    30. int tmpNum = Integer.parseInt( numbers[i] );
    31. if( tmpNum > maxNum )
    32. {
    33. maxNum = tmpNum;
    34. }
    35. sum += tmpNum;
    36. numList.add( tmpNum );
    37. }
    38. int maxMVPCnt = sum / maxNum;
    39. for( int i = maxMVPCnt; i >= 1; i --)
    40. {
    41. if( sum % i != 0 )
    42. {
    43. continue;
    44. }
    45. int aveScroe = sum / i;
    46. int[] tmpSum = new int[ i ];
    47. for( int j = 0; j < tmpSum.length; j ++ )
    48. {
    49. tmpSum[j] = 0;
    50. }
    51. int ret = processAverageScroe( aveScroe, tmpSum, numList );
    52. if( ret != -1 )
    53. {
    54. System.out.println( ret );
    55. return;
    56. }
    57. }
    58. }
    59. private static int processAverageScroe( int score, int[] tmpSum, List numbers)
    60. {
    61. int ret = -1;
    62. int tmpNum = numbers.get( 0 );
    63. numbers.remove( 0 );
    64. for( int i = 0; i < tmpSum.length; i ++ )
    65. {
    66. if( tmpNum + tmpSum[i] > score )
    67. {
    68. continue;
    69. }
    70. tmpSum[i] = tmpSum[i] + tmpNum;
    71. boolean meet = isArrayAllScore( score, tmpSum, numbers );
    72. if( meet )
    73. {
    74. return score;
    75. }
    76. ret = processAverageScroe( score, tmpSum, numbers);
    77. if( ret != -1 )
    78. {
    79. return ret;
    80. }
    81. tmpSum[i] = tmpSum[i] - tmpNum;
    82. }
    83. numbers.add( 0, tmpNum );
    84. return ret;
    85. }
    86. private static boolean isArrayAllScore( int score, int[] tmpSum, List numbers )
    87. {
    88. boolean ret = true;
    89. if( numbers.size() > 0 )
    90. {
    91. return false;
    92. }
    93. for( int i = 0; i < tmpSum.length; i ++ )
    94. {
    95. if( tmpSum[i] != score )
    96. {
    97. return false;
    98. }
    99. }
    100. return ret;
    101. }
    102. }

    JavaScript代码

    1. const rl = require("readline").createInterface({ input: process.stdin });
    2. var iter = rl[Symbol.asyncIterator]();
    3. const readline = async () => (await iter.next()).value;
    4. void async function() {
    5. while (line = await readline()) {
    6. // count 可以忽略
    7. var count = parseInt(line);
    8. line = await readline();
    9. var numberArr = line.split(" ");
    10. processMVPCompetition(numberArr);
    11. }
    12. }();
    13. function processMVPCompetition(numbers) {
    14. var sum = 0;
    15. var maxNum = 0;
    16. var numList = new Array();
    17. for (var i = 0; i < numbers.length; i++) {
    18. var tmpNum = parseInt(numbers[i]);
    19. if (tmpNum > maxNum) {
    20. maxNum = tmpNum;
    21. }
    22. sum += tmpNum;
    23. numList.push(tmpNum);
    24. }
    25. var maxMVPCnt = parseInt( sum / maxNum );
    26. for (var i = maxMVPCnt; i >= 1; i--) {
    27. if (sum % i != 0) {
    28. continue;
    29. }
    30. var aveScroe = sum / i;
    31. var tmpSum = new Array();
    32. for (var j = 0; j < i; j++) {
    33. tmpSum[j] = 0;
    34. }
    35. var ret = processAverageScroe(aveScroe, tmpSum, numList);
    36. if (ret != -1) {
    37. console.log(ret);
    38. return;
    39. }
    40. }
    41. }
    42. function processAverageScroe( score, tmpSum, numbers) {
    43. var ret = -1;
    44. var tmpNum = numbers.shift(0);
    45. for (var i = 0; i < tmpSum.length; i++) {
    46. if (tmpNum + tmpSum[i] > score) {
    47. continue;
    48. }
    49. tmpSum[i] = tmpSum[i] + tmpNum;
    50. var meet = isArrayAllScore(score, tmpSum, numbers);
    51. if (meet) {
    52. return score;
    53. }
    54. ret = processAverageScroe(score, tmpSum, numbers);
    55. if (ret != -1) {
    56. return ret;
    57. }
    58. tmpSum[i] = tmpSum[i] - tmpNum;
    59. }
    60. numbers.unshift( tmpNum );
    61. return ret;
    62. }
    63. function isArrayAllScore(score, tmpSum, numbers) {
    64. var ret = true;
    65. if (numbers.length > 0) {
    66. return false;
    67. }
    68. for (var i = 0; i < tmpSum.length; i++) {
    69. if (tmpSum[i] != score) {
    70. return false;
    71. }
    72. }
    73. return ret;
    74. }

    (完)

  • 相关阅读:
    IOT云平台 simple(3)springboot netty
    Java使用Documents4j实现Word转PDF(知识点+案例)
    基于STM32+物联网设计的货车重量检测系统(OneNet)
    【FDTD 反射、透射、吸收 软件操作】
    Java项目:ssm超市订单管理
    nodejs微信小程序 +python+PHP+图书销售管理系统的设计与实现-网上书店-图书商城-计算机毕业设计
    Android——认识Android (Android发展简介)(一)
    【毕业设计项目】基于ESP32的家庭气象站系统 - stm32 物联网 嵌入式 单片机
    Leo赠书活动-07期 【嵌入式虚拟化技术与应用】文末送书
    【网络】网络编程套接字(一)
  • 原文地址:https://blog.csdn.net/ZiJinShi/article/details/132807904