{ }codelper
averagegroupingcustom sortingP0195

Ranking stations by average temperature

Temperature records sent by several weather stations are grouped by station and ranked. The first line gives the number of records n, and each of the next n lines gives a station name and a temperature (an integer, in degrees) separated by one space. A station's average temperature is the sum of its temperatures divided by its number of records.
Compare averages exactly, including the fractional part. Print the stations one per line, from the highest average temperature. Stations with exactly the same average are ordered by name in dictionary order (alphabetical for lowercase English letters; if one name is the start of another, the shorter comes first). On each line print the station name, the number of records, and the average rounded down to an integer, separated by single spaces. Rounded down means the greatest integer not larger than the average.
For example 7.5 becomes 7, -2.5 becomes -3, and -3 stays -3.

Input
1 ≤ n ≤ 10,000, station names are 1 to 10 lowercase English letters, -50 ≤ temperature ≤ 50
Output
One line per station: name, number of records, average rounded down
Example 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
Input (stdin)

When you run, these lines are fed to input()/stdin in order (the program doesn't stop to ask).

$ Ready

Open this on a computer to write and run code. On mobile you can read the problem and the solutions.

In other languagesShow solutions by language · 8 languages

The trap is which division produces the average.
In Java, C#, C and C++, / between integers keeps only the quotient, so 7.5 and 7 both become 7 and the ranking falls back to name order.
Python // is also a quotient and does the same.
In JS, TS and Craykon, / always divides into decimals.
To compare exactly, either divide as floating point (equal fractions such as 1/3 and 2/6 become exactly the same double) or cross-multiply and compare sumA × countB with sumB × countA as integers.
Rounding down also differs by language.
Python // and math.floor, JS/TS Math.floor, Java Math.floorDiv, C# Math.Floor and Craykon Mathf.Floor go toward the smaller side, so -2.5 becomes -3.
Integer / in C, C++, Java and C#, JS Math.trunc and Craykon Mathf.Quot cut toward 0 and give -2.
In C and C++, subtract 1 when a / b has a remainder and a is negative.
The sort order runs in opposite directions: "larger average first, smaller name first".
In Python, sorting by (average, name) with reverse=True reverses the names too, so use (-average, name) as the key.
Other languages compare the two parts separately in a comparison function.
Craykon groups with Dict() and orders with list.Sort(compare).

Pythonmain.py · 15 lines
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 lines
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 lines
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 lines
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 lines
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 lines
#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 lines
#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 lines
n = Console.ReadLine().ToNumber();total = Dict(); // 관측소 → 기온 합count = Dict(); // 관측소 → 기록 수for (i = 0; i < n; i++){    p = Console.ReadLine().Trim().Split();    name = p[0];    if (!total.Contains(name))    {        total[name] = 0;        count[name] = 0;    }    total[name] += p[1].ToNumber();    count[name] += 1;} // 평균이 큰 것부터, 같으면 이름 차례평균순(x, y){    ax = total[x] / count[x];    ay = total[y] / count[y];    if (ax != ay)    {        return ay - ax;    }    if (x < y)    {        return -1;    }    if (x > y)    {        return 1;    }    return 0;} order = total.Keys;order.Sort(평균순);foreach (s in order){    // 수학.내림은 작은 쪽으로(-2.5 → -3), 수학.몫은 0 쪽으로(-5, 2 → -2)    Console.WriteLine(s + " " + count[s] + " " + Mathf.Floor(total[s] / count[s]));}