체조 대회의 연기 점수를 내는 함수 점수(난도, 버림, 심사 점수들)를 만든다.
난도 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()·표준 입력으로 들어가요(실행 중에 묻지 않아요).
$ 준비됐어요
코드를 입력해 풀려면 PC에서 열어 주세요. 모바일에서는 문제와 풀이를 볼 수 있어요.
다른 언어로는?언어별 풀이 보기 · 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]})처럼 중괄호로 묶어 넘겨요. 크레이콘에는 이 문법이 없어 목록 하나로 받고 점수(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에 배열을 넘기면 복사하지 않고 그 배열을 그대로 받아요. 크레이콘의 목록도 마찬가지예요. 함수 안에서 그대로 정렬하면 부른 쪽 배열의 차례가 바뀌어, 다음에 s[0], s[1]로 꺼낸 주심 점수가 가장 낮은 두 점수가 돼요(예시 첫 줄의 48이 45가 돼요). scores.clone(), (int[])scores.Clone(), 크레이콘 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);}