MVP 争夺战

题目

mvp争夺战

题目描述

在星球争霸篮球赛对抗赛中,强大的宇宙战队,希望每个人都能拿到MVP。

MVP 的条件是,单场最高分得分获得者,可以并列,所以宇宙战队决定在比赛中,尽可能让更多的队员上场,且让所有有得分的队员得分都相同。

然而比赛过程中的每一分钟的得分都只能由某一个人包揽。

输入描述

输入第一行为一个数字t,表示有得分的分钟数( 1 <= t <= 50),第二行为t 个数字,代表每一分钟的得分p(1 <= p <= 50)

输出描述

输出有得分的队员都是MVP 时最少的MVP 得分。


题目分析

首先确定最多可能有多少个队员,对得分数组进行从大到小排序,那么最多的队员数量为

num = totalScore / minuteNum

从num向下递减,当

totalScore % num == 0

此时总分数可以平均分配给每个人,但是由于每分钟只能有一个人得分,所以需要通过方法,对得分数组进行遍历。用 int tempScore表示当前的得分,用ArrayList<Integer> hasVisited表示已经访问过的得分,用ArrayList<Integer> scoreList 记录当前所有的得分

  1. 如果得分集合存在等于 tempScore的值,说明找到了,将tempScore从集合中删除,进行下一次的寻找
  2. 如果得分集合不存在等于tempScore的值,需要在将集合中的数据进行组合,从而寻找,每次将寻找到的组合从得分集合中删除,直至所有满足的组合都被找到
    1. 如果此时找到的组合数等于num,那么当前的分数就是最少MVP的分数
    2. 如果此时找到的组合数不等于(必然是小于)num,那么将 num-- ,再进行下一次循环
寻找剩余集合访问过的集合
11118、7、6、5、4、28
37、6、5、4、28、2
此时遍历完了,未找到,从下一位重新开始遍历,访问过的集合清空,无需删除(其实在此时已经可以直接返回一个值,说明该tempScore无法满足,在后面的代码里偷了个懒,没写)null
118、7、6、5、4、27
46、5、4、27、4
找到了满足tempScore的组合,此时在得分集合中删除访问过的集合,同时将访问集合清空null
118、6、5、28
··········

完整代码

代码如下所示,有很多可修改之处,仅供参考

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Objects;
public class MVPRace {
    public static void main(String[] args) throws IOException {
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        String[] split = in.readLine().split(" ");
        String[] split1 = in.readLine().split(" ");
        int[] minutes = new int[split.length];
        int[] scores = new int[split1.length];
        for (int i = 0; i < split.length; i++) {
            minutes[i] = Integer.parseInt(split[i]);
            scores[i] = Integer.parseInt(split1[i]);
        }
        System.out.println(method(minutes, scores));
    }
    /**
     * 获取有得分的队员都是MVP 时最少的MVP 得分
     * @param minutes 有得分的分钟数
     * @param scores  有得分的分钟的得分
     * @return 最多MVP选手时,MVP得分
     */
    public static int method(int[] minutes, int[] scores){
        int totalScore = 0;
        ArrayList<Integer> scoreList = new ArrayList<>();
        for (int score : scores) {
            totalScore += score;
            scoreList.add(score);
        }
        scoreList.sort((o1, o2) -> o2 - o1);
        int maxNum = totalScore / scoreList.get(0);
        int minScore = 0;
        while (maxNum > 0){
            //最多有maxNum个人,如果能除尽,再去寻找,否则退出
            if (totalScore % maxNum != 0){
                maxNum--;
            }else {
                int tempScore = totalScore / maxNum;
                boolean isFindMVP = true;
                ArrayList<Integer> tempList = new ArrayList<>(scoreList);
                for (int i = 0; i < maxNum; i++) {
                    ArrayList<Integer> hasVisited = new ArrayList<>();
                    isFindMVP = findMVP(tempList, hasVisited, tempScore);
                    if (!isFindMVP){
                        break;
                    }
                    tempList.removeAll(hasVisited);
                }
                if (isFindMVP){
                    minScore = tempScore;
                    break;
                }else {
                    maxNum--;
                }
            }
        }
        return minScore;
    }
    public static boolean findMVP(ArrayList<Integer> scoreList, ArrayList<Integer> hasVisited, Integer tempScore){
        Integer[] integers = scoreList.toArray(new Integer[0]);
        for (Integer integer : integers) {
            if (Objects.equals(integer, tempScore)) {
                hasVisited.add(tempScore);
                return true;
            } else if (integer < tempScore){
                hasVisited.add(integer);
                scoreList.remove(integer);
                boolean mvp = findMVP(scoreList, hasVisited, tempScore - integer);
                scoreList.add(integer);
                if (mvp) {
                    return true;
                }
                scoreList.sort((o1, o2) -> o2 - o1);
                hasVisited.remove(integer);
            }
        }
        return false;
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值