1. 题目
给定一个射击比赛成绩单
包含多个选手若干次射击的成绩分数
请对每个选手按其最高三个分数之和进行降序排名
输出降序排名后的选手ID序列
条件如下:
- 一个选手可以有多个射击成绩的分数 且次序不固定
- 如果一个选手成绩小于三个 则认为选手的所有成绩无效 排名忽略该选手
- 如果选手的成绩之和相等,则成绩相等的选手按照其ID降序排列
输入描述
输入第一行:一个整数 N
表示该场比赛总共进行了N次射击
产生N个成绩分数 2 <= N <= 100
输入第二行 一个长度为N的整数序列
表示参与本次射击的选手Id
0 <= ID <= 99
输入第三行是长度为N的整数序列
表示参与每次射击的选手对应的成绩
0 <= 成绩 <= 100
输出描述
符合题设条件的降序排名后的选手ID序列
输入例子:
13
3,3,7,4,4,4,4,7,7,3,5,5,5
53,80,68,24,39,76,66,16,100,55,53,80,55
输出结果:
5,3,7,4
说明:
该场射击比赛进行了13次,参赛选手为3 4 5 7
3号选手的成绩为53 80 55最高三个成绩的和为 188
4号选手的成绩为24 39 76 66最高三个和为181
5号选手的成绩为53 80 55 最高三个和为188
7号选手成绩为68 16 100 最高三个和184
比较各个选手最高三个成绩的和
3 = 5 > 7 > 4
由于3和5成绩相等 且5 > 3 所以输出为5,3,7,4
2. 答案
class Test {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
while (in.hasNextLine()) {
int n = in.nextInt();
in.nextLine();
String idStr = in.nextLine();
String scoreStr = in.nextLine();
String[] ids = idStr.split(",");
String[] scores = scoreStr.split(",");
Map<Integer, List<Integer>> map = new HashMap<>();
for (int i = 0; i < n; i++) {
int key = Integer.parseInt(ids[i]);
int value = Integer.parseInt(scores[i]);
if (map.containsKey(key)) {
map.get(key).add(value);
} else {
List<Integer> list = new ArrayList<>();
list.add(value);
map.put(key, list);
}
}
solutionStream(map);
}
}
/**
* Stream 翻译称为 “流”,是 Java8 的新特性之一。 Stream 将要处理的元素看作是流,这时可以借助 Stream API 对流中的元素进行中间操作,比如:筛选、排序、排序等
*
* 1.创建Stream : map.entrySet().stream()
* 2.中间操作
* filter: 过滤流,过滤流中的元素,返回一个符合条件的Stream
* sorted: 返回一个排序的Stream
* limit: 返回前n个元素数据组成的Stream。属于短路操作
* map: 转换流,将一种类型的流转换为另外一种流(mapToInt、mapToLong、mapToDouble 返回int、long、double基本类型对应的Stream)
* 3.终止操作
* collect: 聚合操作,封装目标数据,将流转换为其他形式接收,如: List、Set、Map、Array
*
* Java 8 流的新类 java.util.stream.Collectors 实现了 java.util.stream.Collector 接口,同时又提供了大量的方法对流 ( stream ) 的元素执行 map and reduce 操作,或者统计操作
* Collectors.joining() 方法用某个指定的拼接**字符串**把所有元素拼接成一个字符串,并添加可选的前缀和后缀
*
* @param map key是选手的id,value是选手的成绩集合
*/
private static void solutionStream(Map<Integer, List<Integer>> map) {
String collectStr = map.entrySet().stream()
.filter(per -> (per.getValue().size() >= 3)) // 成绩少于3个成绩无效
.sorted((p1, p2) -> {
// 成绩降序→取前三→求和
int sum1 = p1.getValue().stream().sorted(Comparator.reverseOrder()).limit(3).mapToInt(Integer::valueOf).sum();
int sum2 = p2.getValue().stream().sorted(Comparator.reverseOrder()).limit(3).mapToInt(Integer::valueOf).sum();
// 最大成绩降序前三加和降序,加和相同的话Id降序
if (sum1 == sum2) {
return p2.getKey() - p1.getKey();
} else {
return sum2 - sum1;
}
})
.map(Map.Entry::getKey) // 取得员工Id
.map(String::valueOf) // 类型不转没办法joining
.collect(Collectors.joining(",")); // 拼接字符串
System.out.println(collectStr);
}
}
输出结果: