{ }codelper
사전 고치기사전 돌기기준 정해 정렬P0109

실시간 상위 3명

게임 점수판에 점수 변화가 하나씩 들어온다.
첫 줄에 사건 수 q가, 다음 q줄에 사건 "이름 변화량"이 빈칸 하나로 나뉘어 주어진다.
사건마다 그 이름의 점수에 변화량을 더한다.
처음 나온 이름은 0점에서 시작한다.
변화량은 0이거나 음수일 수 있고, 점수도 음수가 될 수 있다.
변화량이 0이어도 그 이름은 점수판에 오른다.
사건 하나를 처리할 때마다, 점수판에 있는 사람 가운데 앞선 세 명을 한 줄에 "이름:점수"로 빈칸 하나씩 띄워 출력한다.
점수가 높은 사람이 앞서고, 점수가 같으면 이름이 사전 순으로 앞선 사람이 앞선다.
사전 순은 앞 글자부터 하나씩 비교해 글자 코드(ASCII)가 작은 쪽이 앞서고(숫자가 영어 소문자보다 앞), 한쪽이 다른 쪽의 앞부분이면 짧은 쪽이 앞선다.
점수판에 세 명이 안 되면 있는 사람을 모두 출력한다.

입력
1 ≤ q ≤ 2000, −100 ≤ 변화량 ≤ 100(정수).
이름은 영어 소문자·숫자 1 ~ 10글자이고, 서로 다른 이름은 많아야 100개
출력
q줄.
줄마다 앞선 사람부터 많아야 세 명의 "이름:점수"
예시 1 · stdin
6
mina 5
joon 3
mina -4
sora 3
dan 7
joon 1
stdout
mina:5
mina:5 joon:3
joon:3 mina:1
joon:3 sora:3 mina:1
dan:7 joon:3 sora:3
dan:7 joon:4 sora:3
예시 2 · stdin
3
kai 0
ari -2
kai -5
stdout
kai:0
kai:0 ari:-2
ari:-2 kai:-5
main.py
입력(stdin)

실행하면 이 줄들이 차례로 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 sys lines = 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;}