게임 점수판에 점수 변화가 하나씩 들어온다. 첫 줄에 사건 수 q가, 다음 q줄에 사건 "이름 변화량"이 빈칸 하나로 나뉘어 주어진다. 사건마다 그 이름의 점수에 변화량을 더한다. 처음 나온 이름은 0점에서 시작한다. 변화량은 0이거나 음수일 수 있고, 점수도 음수가 될 수 있다. 변화량이 0이어도 그 이름은 점수판에 오른다. 사건 하나를 처리할 때마다, 점수판에 있는 사람 가운데 앞선 세 명을 한 줄에 "이름:점수"로 빈칸 하나씩 띄워 출력한다. 점수가 높은 사람이 앞서고, 점수가 같으면 이름이 사전 순으로 앞선 사람이 앞선다. 사전 순은 앞 글자부터 하나씩 비교해 글자 코드(ASCII)가 작은 쪽이 앞서고(숫자가 영어 소문자보다 앞), 한쪽이 다른 쪽의 앞부분이면 짧은 쪽이 앞선다. 점수판에 세 명이 안 되면 있는 사람을 모두 출력한다.
입력
1 ≤ q ≤ 2000, −100 ≤ 변화량 ≤ 100(정수). 이름은 영어 소문자·숫자 1 ~ 10글자이고, 서로 다른 이름은 많아야 100개
실행하면 이 줄들이 차례로 input()·표준 입력으로 들어가요(실행 중에 묻지 않아요).
$ 준비됐어요
코드를 입력해 풀려면 PC에서 열어 주세요. 모바일에서는 문제와 풀이를 볼 수 있어요.
다른 언어로는?언어별 풀이 보기 · 8개 언어 풀이
사전 고치기는 "없으면 0에서 시작해 더하기"예요. 언어마다 한 줄로 쓰는 법과, 없는 열쇠를 읽을 때 무슨 일이 생기는지가 달라요. Python scores[name] += d는 처음 나온 이름에서 KeyError라 scores.get(name, 0) + d나 defaultdict(int)를 써요. JS Map.get은 없으면 undefined라 undefined + 5가 NaN이 되고 오류도 안 나요(?? 0을 붙여요). Java scores.get(name) + d는 null을 int로 풀다가 NullPointerException이라 merge(name, d, Integer::sum)을 쓰고, C# scores[name] += d는 KeyNotFoundException이라 TryGetValue로 읽어요(없으면 0). C++ scores[name] += d는 []가 0을 만들어 줘서 그대로 돼요. 크레이콘은 없는 열쇠를 읽으면 멈추니 만약 (!scores.있나(name)) { scores[name] = 0; }을 먼저 해요. C에는 사전이 없지만 이름이 100개뿐이라 이름 표를 차례로 찾고, 앞선 사람을 세 번 골라요. 순위는 사전을 돌며 (이름, 점수) 짝을 모아 정렬해요: Python sorted(scores.items(), key=lambda kv: (-kv[1], kv[0]))[:3], Java comparingByValue().reversed().thenComparing(comparingByKey()), C# OrderByDescending(kv => kv.Value).ThenBy(kv => kv.Key), C++ partial_sort로 앞 세 자리만. 함정 둘: (점수, 이름)을 reverse=True로 정렬하면 동점일 때 이름까지 z부터 거꾸로 돼요. JS 비교 함수가 b[1] > a[1]처럼 true/false를 돌려주면 음수가 없어서 정렬이 틀어지니 b[1] - a[1]처럼 음수·0·양수를 돌려줘요.
Pythonmain.py · 13 줄
import syslines = sys.stdin.read().split("\n")q = int(lines[0])scores = {}out = []for line in lines[1:q + 1]: name, delta = line.split() scores[name] = scores.get(name, 0) + int(delta) # 처음 나온 이름은 0점부터 # 점수가 높은 사람 먼저, 같으면 이름 사전 순 top = sorted(scores.items(), key=lambda kv: (-kv[1], kv[0]))[:3] out.append(" ".join(f"{n}:{s}" for n, s in top))print("\n".join(out))
JavaScriptmain.js · 13 줄
const lines = require("fs").readFileSync(0, "utf8").split("\n");const q = Number(lines[0]);const scores = new Map();const out = [];for (const line of lines.slice(1, q + 1)) { const [name, delta] = line.trim().split(" "); scores.set(name, (scores.get(name) ?? 0) + Number(delta)); // 없으면 undefined + 수 = NaN const top = [...scores.entries()] .sort((a, b) => b[1] - a[1] || (a[0] < b[0] ? -1 : 1)) // 점수 높은 사람 먼저, 같으면 이름 순 .slice(0, 3); out.push(top.map(([n, s]) => `${n}:${s}`).join(" "));}console.log(out.join("\n"));
TypeScriptmain.ts · 14 줄
import { readFileSync } from "node:fs";const lines: string[] = readFileSync(0, "utf8").split("\n");const q = Number(lines[0]);const scores = new Map<string, number>();const out: string[] = [];for (const line of lines.slice(1, q + 1)) { const [name, delta] = line.trim().split(" "); scores.set(name, (scores.get(name) ?? 0) + Number(delta)); // 없으면 undefined + 수 = NaN const top: [string, number][] = [...scores.entries()] .sort((a, b) => b[1] - a[1] || (a[0] < b[0] ? -1 : 1)) // 점수 높은 사람 먼저, 같으면 이름 순 .slice(0, 3); out.push(top.map(([n, s]) => `${n}:${s}`).join(" "));}console.log(out.join("\n"));
JavaMain.java · 25 줄
import java.io.*;import java.util.*;public class Main { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); int q = Integer.parseInt(br.readLine().trim()); Map<String, Integer> scores = new HashMap<>(); StringBuilder out = new StringBuilder(); Comparator<Map.Entry<String, Integer>> order = Map.Entry.<String, Integer>comparingByValue().reversed().thenComparing(Map.Entry.comparingByKey()); for (int i = 0; i < q; i++) { String[] p = br.readLine().trim().split(" "); scores.merge(p[0], Integer.parseInt(p[1]), Integer::sum); // 없으면 그 값을, 있으면 더한 값을 넣는다 List<Map.Entry<String, Integer>> all = new ArrayList<>(scores.entrySet()); all.sort(order); StringJoiner sj = new StringJoiner(" "); for (int j = 0; j < Math.min(3, all.size()); j++) sj.add(all.get(j).getKey() + ":" + all.get(j).getValue()); out.append(sj).append('\n'); } System.out.print(out); }}
C#Main.cs · 28 줄
using System;using System.Collections.Generic;using System.Linq;using System.Text;class Program{ static void Main() { int q = int.Parse(Console.ReadLine().Trim()); var scores = new Dictionary<string, int>(); var sb = new StringBuilder(); for (int i = 0; i < q; i++) { string[] p = Console.ReadLine().Trim().Split(' '); scores.TryGetValue(p[0], out int now); // 없으면 now = 0 scores[p[0]] = now + int.Parse(p[1]); var top = scores .OrderByDescending(kv => kv.Value) .ThenBy(kv => kv.Key, StringComparer.Ordinal) .Take(3) .Select(kv => $"{kv.Key}:{kv.Value}"); sb.Append(string.Join(" ", top)).Append('\n'); } Console.Write(sb); }}
C++main.cpp · 29 줄
#include <algorithm>#include <iostream>#include <map>#include <string>#include <vector>int main() { int q; std::cin >> q; std::map<std::string, int> scores; std::string out; for (int i = 0; i < q; i++) { std::string name; int delta; std::cin >> name >> delta; scores[name] += delta; // 없는 열쇠는 []가 0으로 만들어 준다 std::vector<std::pair<std::string, int>> all(scores.begin(), scores.end()); // 셋만 필요하니 partial_sort로 앞 세 자리만 맞춘다 size_t k = std::min<size_t>(3, all.size()); std::partial_sort(all.begin(), all.begin() + k, all.end(), [](const auto& a, const auto& b) { if (a.second != b.second) return a.second > b.second; return a.first < b.first; }); for (size_t j = 0; j < k; j++) out += (j ? " " : "") + all[j].first + ":" + std::to_string(all[j].second); out += "\n"; } std::cout << out;}
Cmain.c · 46 줄
#include <stdio.h>#include <string.h>/* C에는 사전이 없다: 이름은 많아야 100개라 이름 표를 차례로 찾는다 */static char names[100][11];static int score[100];static int count = 0;/* i가 j보다 앞서야 하나: 점수가 높거나, 같으면 이름이 사전 순으로 앞선다 */static int before(int i, int j) { if (score[i] != score[j]) return score[i] > score[j]; return strcmp(names[i], names[j]) < 0;}int main(void) { int q; scanf("%d", &q); for (int e = 0; e < q; e++) { char name[11]; int delta, at = -1; scanf("%10s %d", name, &delta); for (int i = 0; i < count; i++) if (strcmp(names[i], name) == 0) { at = i; break; } if (at < 0) { /* 처음 나온 이름은 0점부터 */ at = count++; strcpy(names[at], name); score[at] = 0; } score[at] += delta; /* 세 번 돌며 아직 뽑지 않은 사람 중 가장 앞서는 사람을 고른다 */ int top[3], k = count < 3 ? count : 3; for (int t = 0; t < k; t++) { int best = -1; for (int i = 0; i < count; i++) { int used = 0; for (int u = 0; u < t; u++) used |= top[u] == i; if (!used && (best < 0 || before(i, best))) best = i; } top[t] = best; printf(t ? " %s:%d" : "%s:%d", names[best], score[best]); } printf("\n"); } return 0;}
Craykonmain.cray · 35 줄
q = 콘솔.줄읽기().수로변환();scores = 사전();반복 (e = 0; e < q; e++){ p = 콘솔.줄읽기().공백제거().나누기(); name = p[0]; 만약 (!scores.있나(name)) { scores[name] = 0; // 없는 열쇠를 읽으면 멈추니 먼저 0점으로 넣는다 } scores[name] = scores[name] + p[1].수로변환(); names = scores.열쇠목록; names.정렬(앞선사람먼저); top = []; 반복 (i = 0; i < names.개수 && i < 3; i++) { top.넣기(names[i] + ":" + scores[names[i]]); } 콘솔.쓰기(top.잇기(" "));}// 점수가 높은 사람 먼저, 같으면 이름 사전 순앞선사람먼저(앞, 뒤){ 만약 (scores[앞] != scores[뒤]) { 돌려주기 scores[뒤] - scores[앞]; } 만약 (앞 < 뒤) { 돌려주기 -1; } 돌려주기 1;}