编写一个求体操比赛动作得分的函数 得分(难度, 舍去数, 各评分)。 难度 d 和舍去数 k 一定会收到,后面的评分可以接收任意个。 函数把收到的评分中最低的 k 个和最高的 k 个舍去,返回剩下评分之和乘以 d 的值。 即使有多个相同的分数,也只从低的一侧舍去 k 个、从高的一侧舍去 k 个。 没有剩下的评分时,和为 0。 每套动作调用这个函数两次。 正式得分把所有裁判的评分传进去,用 得分(d, k, s1, s2, …, sm) 求出。 主裁得分只传入该行最前面两位裁判(主裁)的评分,什么都不舍去,用 得分(d, 0, s1, s2) 求出。 第一行给出动作数 q。 接下来 q 行,每套动作给出 d、k,然后是评分 s1, s2, …, sm,用一个空格隔开。 裁判人数 m 每行可能不同,不另外给出。 每套动作在一行中按这个顺序输出正式得分和主裁得分,用一个空格隔开。 评测只看输出,不检查函数是怎么写的。 不过请试着写一个带有可以接收任意个值的参数(没有这种语法的语言用一个列表或数组)的函数,并调用它两次来解。
输入
1 ≤ q ≤ 1,000。 1 ≤ d ≤ 10。 2 ≤ m ≤ 100。 0 ≤ k 且 2 × k ≤ m。 0 ≤ 评分 ≤ 100(都是整数)
输出
q 行,每行是正式得分和主裁得分
样例 1 · stdin
3
3 1 9 7 8 10
2 0 5 6 7
1 1 4 100
stdout
51 48
36 22
0 104
main.py
错误列表00F8 ↓ · ⇧F8 ↑
输入(stdin)
运行时这些行会依次作为 input()/标准输入传入(运行中不会等待输入)。
$ 就绪
请在电脑上打开以编写和运行代码。在手机上可以查看题目和题解。
其他语言怎么写?查看各语言题解 · 8 种语言题解
接收任意个值的参数,各语言写法不同。 Python def score(d, k, *scores),JS function score(d, k, ...scores),TS ...scores: number[],Java static long score(int d, int k, int... scores),C# static long Score(int d, int k, params int[] scores),一个函数里只能用一次。 在 JS・TS・Java・C# 中它必须是最后一个参数,而 Python 可以在 *scores 后面再写只能按名字传的参数(陷阱 ③)。 C 的 ...(stdarg.h)不知道收到了几个,也不能把数组展开传进去,所以像 (const int *scores, int m) 这样接收数组和个数;C++ 用 std::vector<int> 接收,调用时像 score(d, 0, {s[0], s[1]}) 这样用花括号括起来。 Craykon 没有这种语法,用一个列表接收,像 得分(d, 0, [s[0], s[1]]) 这样调用。 调用的一侧也不同。 Python 的 score(*nums) 和 JS 的 score(...nums) 把列表展开,前两个给 d 和 k,其余给 scores。 TS 会拒绝 score(...nums)(TS2556:不知道展开后有几个落在 d 和 k 的位置)。 所以写成 score(d, k, ...nums.slice(2)),只在剩余参数的位置展开。 Java 和 C# 直接把数组传过去就行。 陷阱 ① 收到的是不是副本,各语言不同。 Python 的 *scores 是新的元组,JS・TS 的 ...scores 是新的数组,所以在函数里排序不会影响调用方。 但把数组传给 Java 的 int... 和 C# 的 params 时不会复制,函数收到的就是那个数组。 Craykon 的列表也一样。 在函数里直接排序会改变调用方数组的顺序,之后用 s[0]、s[1] 取出的主裁评分就成了最低的两个分数(样例第一行的 48 会变成 45)。 用 scores.clone()、(int[])scores.Clone()、Craykon scores.子列表(0, scores.数量) 对副本排序。 C++ 按值接收 vector 就是副本。 ② Python 的 *scores 是元组,没有 scores.sort()(AttributeError)。 要用 sorted(scores)。 ③ 在 Python 中像 def score(d, *scores, k=0) 这样写在 *scores 后面的参数只能按名字传。 按位置传的 k 会混进评分里。 ④ 把舍去后剩下的范围写成 Python 的 ordered[k:-k],k 为 0 时是 [0:0],成了空列表。 要写成 ordered[k:len(ordered) - k]。 ⑤ JS・TS 的 sort() 不给比较函数时连数字也按字符串顺序排,10 会排在 9 前面,100 排在 20 前面。 要写成 sort((a, b) => a - b)。
Pythonmain.py · 20 行
import sysdef score(d, k, *scores): """난도 d와 버림 k는 꼭 받고, 심사 점수는 몇 개든 받는다(scores는 튜플).""" ordered = sorted(scores) # 튜플은 고칠 수 없으니 정렬한 새 목록을 만든다 kept = ordered[k:len(ordered) - k] # [k:-k]는 k가 0일 때 빈 목록이 된다 return d * sum(kept)lines = sys.stdin.read().split("\n")q = int(lines[0])out = []for i in range(1, q + 1): nums = list(map(int, lines[i].split())) d, k = nums[0], nums[1] official = score(*nums) # 목록을 펼쳐 넘긴다: 앞의 둘은 d와 k로, 나머지는 scores로 head = score(d, 0, nums[2], nums[3]) # 주심 두 명만 따로 넘긴다 out.append(f"{official} {head}")print("\n".join(out))
JavaScriptmain.js · 19 行
// 난도 d와 버림 k는 꼭 받고, 심사 점수는 몇 개든 받는다(...scores는 새 배열)function score(d, k, ...scores) { scores.sort((a, b) => a - b); // 비교 함수가 없으면 문자열 순서로 정렬된다 let sum = 0; for (let i = k; i < scores.length - k; i++) sum += scores[i]; return d * sum;}const lines = require("fs").readFileSync(0, "utf8").split("\n");const q = Number(lines[0]);const out = [];for (let i = 1; i <= q; i++) { const nums = lines[i].trim().split(/\s+/).map(Number); const [d, k] = nums; const official = score(...nums); // 배열을 펼쳐 넘긴다: 값이 복사되므로 nums는 그대로다 const head = score(d, 0, nums[2], nums[3]); // 주심 두 명만 따로 넘긴다 out.push(official + " " + head);}console.log(out.join("\n"));
TypeScriptmain.ts · 22 行
import { readFileSync } from "node:fs";// 난도 d와 버림 k는 꼭 받고, 심사 점수는 몇 개든 받는다(...scores는 새 배열)function score(d: number, k: number, ...scores: number[]): number { scores.sort((a, b) => a - b); // 비교 함수가 없으면 문자열 순서로 정렬된다 let sum = 0; for (let i = k; i < scores.length - k; i++) sum += scores[i]; return d * sum;}const lines: string[] = readFileSync(0, "utf8").split("\n");const q: number = Number(lines[0]);const out: string[] = [];for (let i = 1; i <= q; i++) { const nums: number[] = lines[i].trim().split(/\s+/).map(Number); const [d, k] = nums; // score(...nums)는 d와 k 자리에 몇 개가 들어갈지 몰라 TS가 막는다: 나머지 매개변수 자리만 펼친다 const official: number = score(d, k, ...nums.slice(2)); const head: number = score(d, 0, nums[2], nums[3]); // 주심 두 명만 따로 넘긴다 out.push(official + " " + head);}console.log(out.join("\n"));
JavaMain.java · 32 行
import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.util.Arrays;public class Main { // 난도 d와 버림 k는 꼭 받고, 심사 점수는 몇 개든 받는다(int...은 맨 뒤에만 쓸 수 있다) static long score(int d, int k, int... scores) { // 배열을 그대로 넘겨받으면 부른 쪽 배열과 같은 것이다: 복사본을 정렬한다 int[] ordered = scores.clone(); Arrays.sort(ordered); long sum = 0; for (int i = k; i < ordered.length - k; i++) sum += ordered[i]; return d * sum; } public static void main(String[] args) throws IOException { BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); int q = Integer.parseInt(in.readLine().trim()); StringBuilder out = new StringBuilder(); for (int line = 0; line < q; line++) { String[] parts = in.readLine().trim().split("\\s+"); int d = Integer.parseInt(parts[0]), k = Integer.parseInt(parts[1]); int[] s = new int[parts.length - 2]; for (int i = 0; i < s.length; i++) s[i] = Integer.parseInt(parts[i + 2]); long official = score(d, k, s); // 배열을 통째로 넘긴다 long head = score(d, 0, s[0], s[1]); // 주심 두 명만 따로 넘긴다 out.append(official).append(' ').append(head).append('\n'); } System.out.print(out); }}
C#Main.cs · 33 行
using System;using System.Text;class Program{ // 난도 d와 버림 k는 꼭 받고, 심사 점수는 몇 개든 받는다(params는 맨 뒤에만 쓸 수 있다) static long Score(int d, int k, params int[] scores) { // 배열을 그대로 넘겨받으면 부른 쪽 배열과 같은 것이다: 복사본을 정렬한다 int[] ordered = (int[])scores.Clone(); Array.Sort(ordered); long sum = 0; for (int i = k; i < ordered.Length - k; i++) sum += ordered[i]; return d * sum; } static void Main() { int q = int.Parse(Console.ReadLine()); var sb = new StringBuilder(); for (int line = 0; line < q; line++) { string[] parts = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries); int d = int.Parse(parts[0]), k = int.Parse(parts[1]); int[] s = new int[parts.Length - 2]; for (int i = 0; i < s.Length; i++) s[i] = int.Parse(parts[i + 2]); long official = Score(d, k, s); // 배열을 통째로 넘긴다 long head = Score(d, 0, s[0], s[1]); // 주심 두 명만 따로 넘긴다 sb.Append(official).Append(' ').Append(head).Append('\n'); } Console.Write(sb); }}
C++main.cpp · 30 行
#include <algorithm>#include <iostream>#include <sstream>#include <string>#include <vector>// 심사 점수는 vector로 받는다. 값으로 받으면 복사본이라 마음대로 정렬해도 된다static long long score(int d, int k, std::vector<int> scores) { std::sort(scores.begin(), scores.end()); long long sum = 0; for (int i = k; i < static_cast<int>(scores.size()) - k; i++) sum += scores[i]; return d * sum;}int main() { std::string line; std::getline(std::cin, line); int q = std::stoi(line); for (int t = 0; t < q; t++) { std::getline(std::cin, line); std::istringstream in(line); int d, k, x; in >> d >> k; std::vector<int> s; while (in >> x) s.push_back(x); long long official = score(d, k, s); long long head = score(d, 0, {s[0], s[1]}); // 주심 두 명만 중괄호로 묶어 넘긴다 std::cout << official << ' ' << head << '\n'; }}
Cmain.c · 41 行
#include <stdio.h>#include <stdlib.h>#include <string.h>#define MAXM 100static int by_value(const void *a, const void *b) { return *(const int *)a - *(const int *)b;}/* C의 ...(stdarg.h)는 개수를 알 수 없고 배열을 펼쳐 넘길 수도 없다: 배열과 개수를 함께 받는다 */static long long score(int d, int k, const int *scores, int m) { int ordered[MAXM]; memcpy(ordered, scores, (size_t)m * sizeof(int)); /* 부른 쪽 배열은 그대로 둔다 */ qsort(ordered, (size_t)m, sizeof(int), by_value); long long sum = 0; for (int i = k; i < m - k; i++) sum += ordered[i]; return d * sum;}int main(void) { int q; static char line[1024]; scanf("%d ", &q); for (int t = 0; t < q; t++) { if (!fgets(line, sizeof line, stdin)) break; int d, k, used = 0, m = 0, s[MAXM]; char *p = line; sscanf(p, "%d %d%n", &d, &k, &used); p += used; while (m < MAXM && sscanf(p, "%d%n", &s[m], &used) == 1) { p += used; m++; } long long official = score(d, k, s, m); int heads[2] = {s[0], s[1]}; /* 주심 두 명만 따로 넘긴다 */ long long head = score(d, 0, heads, 2); printf("%lld %lld\n", official, head); } return 0;}
Craykonmain.cray · 26 行
// 크레이콘에는 '몇 개든 받는 매개변수'가 없다 — 심사 점수를 목록 하나로 받는다점수(d, k, scores){ // 받은 목록은 부른 쪽 목록과 같은 것이다: 복사본을 정렬한다 ordered = scores.子列表(0, scores.数量); ordered.排序(); sum = 0; 循环 (i = k; i < ordered.数量 - k; i++) { sum += ordered[i]; } 返回 d * sum;}q = 控制台.读行().转数字();循环 (t = 0; t < q; t++){ nums = 控制台.读数字(); d = nums[0]; k = nums[1]; s = nums.子列表(2, nums.数量 - 2); official = 점수(d, k, s); // 주심 두 명만 새 목록으로 묶어 넘긴다 head = 점수(d, 0, [s[0], s[1]]); 控制台.输出(official + " " + head);}