题目
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 记录当前所有的得分
- 如果得分集合存在等于 tempScore的值,说明找到了,将tempScore从集合中删除,进行下一次的寻找
- 如果得分集合不存在等于tempScore的值,需要在将集合中的数据进行组合,从而寻找,每次将寻找到的组合从得分集合中删除,直至所有满足的组合都被找到
- 如果此时找到的组合数等于num,那么当前的分数就是最少MVP的分数
- 如果此时找到的组合数不等于(必然是小于)num,那么将 num-- ,再进行下一次循环
寻找 | 剩余 | 集合 | 访问过的集合 |
11 | 11 | 8、7、6、5、4、2 | 8 |
3 | 7、6、5、4、2 | 8、2 | |
此时遍历完了,未找到,从下一位重新开始遍历,访问过的集合清空,无需删除(其实在此时已经可以直接返回一个值,说明该tempScore无法满足,在后面的代码里偷了个懒,没写) | null | ||
11 | 8、7、6、5、4、2 | 7 | |
4 | 6、5、4、2 | 7、4 | |
找到了满足tempScore的组合,此时在得分集合中删除访问过的集合,同时将访问集合清空 | null | ||
11 | 8、6、5、2 | 8 | |
·········· |
完整代码
代码如下所示,有很多可修改之处,仅供参考
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;
}
}