{ }codelper
方法记录列表P0080

积分榜

把球队写成一个类,并定义计算积分的方法 points()(积分 = 3 × 胜 + 平,负得 0 分)。
第一行给出球队数 n,接下来 n 行给出 "名字 胜 平 负",用一个空格分隔。
把球队对象列表按以下顺序排序,每个球队输出一行 "名字 积分":积分高的在前;积分相同则胜场多的在前;积分和胜场都相同则输入中先出现的在前。

输入
1 ≤ n ≤ 2000,0 ≤ 胜、平、负 ≤ 100(整数)。
名字为 1 到 10 个小写英文字母或数字,同一名字可能再次出现
输出
n 行,每行名字和积分用一个空格分隔
样例 1 · stdin
5
lions 3 1 2
tigers 2 4 0
bears 3 1 0
hawks 0 5 1
owls 1 2 3
stdout
lions 10
bears 10
tigers 10
owls 5
hawks 5
main.py
输入(stdin)

运行时这些行会依次作为 input()/标准输入传入(运行中不会等待输入)。

$ 就绪

请在电脑上打开以编写和运行代码。在手机上可以查看题目和题解。

其他语言怎么写?查看各语言题解 · 6 种语言题解

本题只接受有类的 Python、JavaScript、TypeScript、Java、C#、C++(C 没有类,Craykon 还不能定义类)。
排序依据是方法的结果而不是字段:Python key=lambda t: (t.points(), t.wins),Java Comparator.comparingInt(Team::points).thenComparingInt(Team::getWins),C# OrderByDescending(t => t.Points()).ThenByDescending(t => t.Wins)。
最后一条规则"相同则按输入顺序"在稳定排序下自然成立。
Python sort、JS/TS Array.prototype.sort(自 ES2019 起)、Java List.sort(对象)、C# LINQ OrderBy 是稳定的;C# List.Sort 和 C++ std::sort 不稳定,所以 C++ 要用 std::stable_sort。
还有三个陷阱。
Python 中先升序排序再 reverse(),并列者之间的顺序也会被反转(reverse=True 会保持并列顺序)。
JS 的比较函数若像 a.points() < b.points() 那样返回 true/false,就永远不会返回负数,排序会出错;请像 b.points() - a.points() 那样返回负数、0、正数。
Java 的 reversed() 会反转此前串起来的整个比较器,所以 comparingInt(...).reversed().thenComparingInt(...).reversed() 会让积分又变回升序。

Pythonmain.py · 24 行
import sys  class Team:    def __init__(self, name, wins, draws, losses):        self.name = name        self.wins = wins        self.draws = draws        self.losses = losses     def points(self):        return 3 * self.wins + self.draws  lines = sys.stdin.read().split("\n")n = int(lines[0])teams = []for line in lines[1:n + 1]:    name, w, d, l = line.split()    teams.append(Team(name, int(w), int(d), int(l))) # 정렬은 안정적이라 승점·승수가 같으면 입력 차례가 남는다teams.sort(key=lambda t: (t.points(), t.wins), reverse=True)print("\n".join(f"{t.name} {t.points()}" for t in teams))
JavaScriptmain.js · 24 行
class Team {  constructor(name, wins, draws, losses) {    this.name = name;    this.wins = wins;    this.draws = draws;    this.losses = losses;  }   points() {    return 3 * this.wins + this.draws;  }} const lines = require("fs").readFileSync(0, "utf8").split("\n");const n = Number(lines[0]);const teams = [];for (let i = 1; i <= n; i++) {  const [name, w, d, l] = lines[i].trim().split(" ");  teams.push(new Team(name, Number(w), Number(d), Number(l)));} // 비교 함수는 음수·0·양수를 돌려줘야 한다. sort는 안정적이라 같으면 입력 차례가 남는다teams.sort((a, b) => b.points() - a.points() || b.wins - a.wins);console.log(teams.map((t) => `${t.name} ${t.points()}`).join("\n"));
TypeScriptmain.ts · 31 行
import { readFileSync } from "node:fs"; class Team {  readonly name: string;  readonly wins: number;  readonly draws: number;  readonly losses: number;   constructor(name: string, wins: number, draws: number, losses: number) {    this.name = name;    this.wins = wins;    this.draws = draws;    this.losses = losses;  }   points(): number {    return 3 * this.wins + this.draws;  }} const lines: string[] = readFileSync(0, "utf8").split("\n");const n: number = Number(lines[0]);const teams: Team[] = [];for (let i = 1; i <= n; i++) {  const [name, w, d, l] = lines[i].trim().split(" ");  teams.push(new Team(name, Number(w), Number(d), Number(l)));} // 비교 함수는 음수·0·양수를 돌려줘야 한다. sort는 안정적이라 같으면 입력 차례가 남는다teams.sort((a, b) => b.points() - a.points() || b.wins - a.wins);console.log(teams.map((t) => `${t.name} ${t.points()}`).join("\n"));
JavaMain.java · 40 行
import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.util.ArrayList;import java.util.Comparator;import java.util.List; class Team {    private final String name;    private final int wins, draws, losses;     Team(String name, int wins, int draws, int losses) {        this.name = name;        this.wins = wins;        this.draws = draws;        this.losses = losses;    }     String getName() { return name; }    int getWins() { return wins; }    int points() { return 3 * wins + draws; }} public class Main {    public static void main(String[] args) throws IOException {        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));        int n = Integer.parseInt(in.readLine().trim());        List<Team> teams = new ArrayList<>();        for (int i = 0; i < n; i++) {            String[] p = in.readLine().trim().split(" ");            teams.add(new Team(p[0], Integer.parseInt(p[1]), Integer.parseInt(p[2]), Integer.parseInt(p[3])));        }         // List.sort(객체)는 안정 정렬이라 같으면 입력 차례가 남는다        teams.sort(Comparator.comparingInt(Team::points).thenComparingInt(Team::getWins).reversed());        StringBuilder out = new StringBuilder();        for (Team t : teams) out.append(t.getName()).append(' ').append(t.points()).append('\n');        System.out.print(out);    }}
C#Main.cs · 42 行
using System;using System.Collections.Generic;using System.Linq;using System.Text; class Team{    public string Name { get; }    public int Wins { get; }    public int Draws { get; }    public int Losses { get; }     public Team(string name, int wins, int draws, int losses)    {        Name = name;        Wins = wins;        Draws = draws;        Losses = losses;    }     public int Points() => 3 * Wins + Draws;} class Program{    static void Main()    {        int n = int.Parse(Console.ReadLine());        var teams = new List<Team>();        for (int i = 0; i < n; i++)        {            string[] p = Console.ReadLine().Trim().Split(' ');            teams.Add(new Team(p[0], int.Parse(p[1]), int.Parse(p[2]), int.Parse(p[3])));        }         // List.Sort는 안정 정렬이 아니다. OrderBy는 안정이라 같으면 입력 차례가 남는다        var ranked = teams.OrderByDescending(t => t.Points()).ThenByDescending(t => t.Wins);        var sb = new StringBuilder();        foreach (var t in ranked) sb.Append($"{t.Name} {t.Points()}\n");        Console.Write(sb);    }}
C++main.cpp · 39 行
#include <algorithm>#include <iostream>#include <string>#include <utility>#include <vector> class Team {public:    Team(std::string name, int wins, int draws, int losses)        : name_(std::move(name)), wins_(wins), draws_(draws), losses_(losses) {}     const std::string& name() const { return name_; }    int wins() const { return wins_; }    int points() const { return 3 * wins_ + draws_; } private:    std::string name_;    int wins_, draws_, losses_;}; int main() {    std::ios::sync_with_stdio(false);    int n;    std::cin >> n;    std::vector<Team> teams;    for (int i = 0; i < n; i++) {        std::string name;        int w, d, l;        std::cin >> name >> w >> d >> l;        teams.emplace_back(name, w, d, l);    }     // std::sort는 안정 정렬이 아니다. stable_sort라야 같으면 입력 차례가 남는다    std::stable_sort(teams.begin(), teams.end(), [](const Team& a, const Team& b) {        if (a.points() != b.points()) return a.points() > b.points();        return a.wins() > b.wins();    });    for (const Team& t : teams) std::cout << t.name() << ' ' << t.points() << '\n';}