{ }codelper
평균묶기기준 정해 정렬P0195

관측소 평균 기온 순위

여러 기상 관측소가 보낸 기온 기록을 관측소별로 모아 순위를 매긴다. 첫 줄에 기록의 수 n이, 다음 n줄에 기록마다 관측소 이름과 기온(정수, 도)이 빈칸 하나로 띄워 주어진다. 한 관측소의 평균 기온은 그 관측소 기록의 기온 합을 기록 수로 나눈 값이다.
소수 부분까지 그대로 비교한다. 평균 기온이 높은 관측소부터 한 줄에 하나씩 출력하라. 평균 기온이 정확히 같은 관측소끼리는 이름의 사전 순(영어 소문자의 알파벳 순, 앞부분이 같으면 짧은 이름이 먼저)으로 놓는다. 줄마다 관측소 이름, 기록 수, 평균 기온을 내림한 정수를 빈칸 하나씩으로 띄워 출력하라. 내림한 정수는 평균보다 크지 않은 가장 큰 정수이다.
예를 들어 7.5는 7, -2.5는 -3, -3은 -3이다.

입력
1 ≤ n ≤ 10,000, 관측소 이름은 영어 소문자 1 ~ 10글자, -50 ≤ 기온 ≤ 50
출력
관측소 수만큼의 줄, 줄마다 이름·기록 수·내림한 평균
예시 1 · stdin
9
seoul 3
busan 8
seoul -2
jeju 9
busan 7
daegu -3
incheon 7
daegu -2
incheon 8
stdout
jeju 1 9
busan 2 7
incheon 2 7
seoul 2 0
daegu 2 -3
main.py
입력(stdin)

실행하면 이 줄들이 차례로 input()·표준 입력으로 들어가요(실행 중에 묻지 않아요).

$ 준비됐어요

코드를 입력해 풀려면 PC에서 열어 주세요. 모바일에서는 문제와 풀이를 볼 수 있어요.

다른 언어로는?언어별 풀이 보기 · 8개 언어 풀이

평균을 어떤 나눗셈으로 내느냐가 이 문제의 함정이에요.
Java·C#·C·C++에서 정수끼리 /로 나누면 몫만 남아서 7.5와 7이 둘 다 7이 되고, 순위가 이름 차례로 뒤바뀌어요.
Python //도 몫이라 마찬가지예요.
JS·TS·크레이콘의 /는 언제나 소수까지 나눠요.
정확히 비교하려면 실수로 나누거나(같은 분수 1/3과 2/6은 똑같은 실수가 돼요), 엇갈려 곱해 합A × 수B와 합B × 수A를 정수로 비교해요.
내림도 언어마다 달라요.
Python //와 math.floor, JS·TS Math.floor, Java Math.floorDiv, C# Math.Floor, 크레이콘 수학.내림은 작은 쪽으로 가서 -2.5가 -3이에요.
C·C++·Java·C#의 정수 /, JS Math.trunc, 크레이콘 수학.몫은 0 쪽으로 버려서 -2가 돼요.
C·C++에서는 a / b에 나머지가 있고 a가 음수이면 1을 빼요.
정렬 기준은 "평균은 큰 것부터, 이름은 작은 것부터"로 방향이 반대예요.
Python에서 (평균, 이름)으로 reverse=True를 하면 이름까지 거꾸로 돼서, (-평균, 이름)을 열쇠로 써요.
다른 언어는 비교 함수에서 둘을 따로 비교해요.
크레이콘은 사전()으로 묶고 목록.정렬(비교함수)로 줄 세워요.

Pythonmain.py · 15 줄
import sys lines = sys.stdin.read().split("\n")n = int(lines[0])total = {}   # 관측소 → 기온 합count = {}   # 관측소 → 기록 수for line in lines[1:n + 1]:    name, t = line.split()    total[name] = total.get(name, 0) + int(t)    count[name] = count.get(name, 0) + 1 # 평균은 나눗셈으로(소수까지) — 평균이 큰 것부터, 같으면 이름 차례order = sorted(total, key=lambda s: (-total[s] / count[s], s))for s in order:    print(s, count[s], total[s] // count[s])  # //는 내림이라 -2.5 → -3
JavaScriptmain.js · 13 줄
const lines = require("fs").readFileSync(0, "utf8").split("\n");const n = Number(lines[0]);const total = new Map(); // 관측소 → 기온 합const count = new Map(); // 관측소 → 기록 수for (let i = 1; i <= n; i++) {  const [name, t] = lines[i].trim().split(" ");  total.set(name, (total.get(name) ?? 0) + Number(t));  count.set(name, (count.get(name) ?? 0) + 1);}const avg = (s) => total.get(s) / count.get(s);const order = [...total.keys()].sort((x, y) => avg(y) - avg(x) || (x < y ? -1 : x > y ? 1 : 0));// Math.floor는 내림(-2.5 → -3), Math.trunc는 0 쪽으로(-2)console.log(order.map((s) => `${s} ${count.get(s)} ${Math.floor(avg(s))}`).join("\n"));
TypeScriptmain.ts · 14 줄
import { readFileSync } from "node:fs";const lines: string[] = readFileSync(0, "utf8").split("\n");const n = Number(lines[0]);const total = new Map<string, number>(); // 관측소 → 기온 합const count = new Map<string, number>(); // 관측소 → 기록 수for (let i = 1; i <= n; i++) {  const [name, t] = lines[i].trim().split(" ");  total.set(name, (total.get(name) ?? 0) + Number(t));  count.set(name, (count.get(name) ?? 0) + 1);}const avg = (s: string): number => total.get(s)! / count.get(s)!;const order: string[] = [...total.keys()].sort((x, y) => avg(y) - avg(x) || (x < y ? -1 : x > y ? 1 : 0));// Math.floor는 내림(-2.5 → -3), Math.trunc는 0 쪽으로(-2)console.log(order.map((s) => `${s} ${count.get(s)} ${Math.floor(avg(s))}`).join("\n"));
JavaMain.java · 35 줄
import java.io.BufferedReader;import java.io.InputStreamReader;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map; public class Main {    public static void main(String[] args) throws Exception {        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));        int n = Integer.parseInt(in.readLine().trim());        Map<String, Integer> total = new HashMap<>(); // 관측소 → 기온 합        Map<String, Integer> count = new HashMap<>(); // 관측소 → 기록 수        for (int i = 0; i < n; i++) {            String[] p = in.readLine().trim().split(" ");            total.merge(p[0], Integer.parseInt(p[1]), Integer::sum);            count.merge(p[0], 1, Integer::sum);        }        List<String> order = new ArrayList<>(total.keySet());        // 정수끼리 나누면 몫만 남는다 → 엇갈려 곱해 정확히 비교한다(a/b > c/d ⇔ a·d > c·b, b·d > 0)        order.sort((x, y) -> {            long left = (long) total.get(y) * count.get(x);            long right = (long) total.get(x) * count.get(y);            if (left != right) return Long.compare(left, right);            return x.compareTo(y);        });        StringBuilder out = new StringBuilder();        for (String s : order) {            // Math.floorDiv는 내림(-5, 2 → -3), / 는 0 쪽으로(-2)            out.append(s).append(' ').append(count.get(s)).append(' ')               .append(Math.floorDiv(total.get(s), count.get(s))).append('\n');        }        System.out.print(out);    }}
C#Main.cs · 36 줄
using System;using System.Collections.Generic;using System.Text; class Program{    static void Main()    {        int n = int.Parse(Console.ReadLine());        var total = new Dictionary<string, int>(); // 관측소 → 기온 합        var count = new Dictionary<string, int>(); // 관측소 → 기록 수        for (int i = 0; i < n; i++)        {            string[] p = Console.ReadLine().Trim().Split(' ');            total[p[0]] = total.GetValueOrDefault(p[0]) + int.Parse(p[1]);            count[p[0]] = count.GetValueOrDefault(p[0]) + 1;        }        var order = new List<string>(total.Keys);        // 정수끼리 나누면 몫만 남는다 → 엇갈려 곱해 정확히 비교한다        order.Sort((x, y) =>        {            long left = (long)total[y] * count[x];            long right = (long)total[x] * count[y];            if (left != right) return left.CompareTo(right);            return string.CompareOrdinal(x, y);        });        var sb = new StringBuilder();        foreach (string s in order)        {            // (int)Math.Floor는 내림(-2.5 → -3), 정수 / 는 0 쪽으로(-2)            int floorAvg = (int)Math.Floor((double)total[s] / count[s]);            sb.Append(s).Append(' ').Append(count[s]).Append(' ').Append(floorAvg).Append('\n');        }        Console.Write(sb);    }}
C++main.cpp · 31 줄
#include <algorithm>#include <iostream>#include <map>#include <string>#include <vector> int main() {    std::ios::sync_with_stdio(false);    int n;    std::cin >> n;    std::map<std::string, std::pair<long long, long long>> st; // 관측소 → (합, 수)    for (int i = 0; i < n; i++) {        std::string name;        int t;        std::cin >> name >> t;        st[name].first += t;        st[name].second++;    }    std::vector<std::pair<std::string, std::pair<long long, long long>>> v(st.begin(), st.end());    // 엇갈려 곱해 정확히 비교한다: a/b > c/d ⇔ a·d > c·b    std::sort(v.begin(), v.end(), [](const auto& x, const auto& y) {        long long left = x.second.first * y.second.second, right = y.second.first * x.second.second;        if (left != right) return left > right;        return x.first < y.first;    });    for (const auto& [name, sc] : v) {        long long q = sc.first / sc.second;            // 0 쪽으로 버린 몫        if (sc.first % sc.second != 0 && sc.first < 0) q--; // 음수는 하나 더 내린다        std::cout << name << ' ' << sc.second << ' ' << q << '\n';    }}
Cmain.c · 59 줄
#include <stdio.h>#include <stdlib.h>#include <string.h> typedef struct {    char name[11];    int t;} Rec; typedef struct {    const char *name;    long long sum;    long long cnt;} Station; static Rec recs[10000];static Station st[10000]; static int by_name(const void *a, const void *b) {    return strcmp(((const Rec *)a)->name, ((const Rec *)b)->name);} /* 평균이 큰 것부터: a/b > c/d ⇔ a·d > c·b (b, d > 0) — 정수 나눗셈 없이 정확히 */static int by_avg(const void *pa, const void *pb) {    const Station *x = pa, *y = pb;    long long left = y->sum * x->cnt, right = x->sum * y->cnt;    if (left != right) return left < right ? -1 : 1;    return strcmp(x->name, y->name);} /* 내림: C의 / 는 0 쪽으로 버리므로(-5 / 2 == -2) 음수에서 하나 더 내린다 */static long long floor_div(long long a, long long b) {    long long q = a / b;    if (a % b != 0 && a < 0) q--;    return q;} int main(void) {    int n;    scanf("%d", &n);    for (int i = 0; i < n; i++) scanf("%10s %d", recs[i].name, &recs[i].t);    qsort(recs, n, sizeof recs[0], by_name); /* 같은 이름끼리 붙여 묶는다 */    int k = 0;    for (int i = 0; i < n; i++) {        if (k == 0 || strcmp(st[k - 1].name, recs[i].name) != 0) {            st[k].name = recs[i].name;            st[k].sum = 0;            st[k].cnt = 0;            k++;        }        st[k - 1].sum += recs[i].t;        st[k - 1].cnt++;    }    qsort(st, k, sizeof st[0], by_avg);    for (int i = 0; i < k; i++) {        printf("%s %lld %lld\n", st[i].name, st[i].cnt, floor_div(st[i].sum, st[i].cnt));    }    return 0;}
Craykonmain.cray · 43 줄
n = 콘솔.줄읽기().수로변환();total = 사전(); // 관측소 → 기온 합count = 사전(); // 관측소 → 기록 수반복 (i = 0; i < n; i++){    p = 콘솔.줄읽기().공백제거().나누기();    name = p[0];    만약 (!total.있나(name))    {        total[name] = 0;        count[name] = 0;    }    total[name] += p[1].수로변환();    count[name] += 1;} // 평균이 큰 것부터, 같으면 이름 차례평균순(x, y){    ax = total[x] / count[x];    ay = total[y] / count[y];    만약 (ax != ay)    {        돌려주기 ay - ax;    }    만약 (x < y)    {        돌려주기 -1;    }    만약 (x > y)    {        돌려주기 1;    }    돌려주기 0;} order = total.열쇠목록;order.정렬(평균순);각각 (s 에서 order){    // 수학.내림은 작은 쪽으로(-2.5 → -3), 수학.몫은 0 쪽으로(-5, 2 → -2)    콘솔.쓰기(s + " " + count[s] + " " + 수학.내림(total[s] / count[s]));}