問題の演習6つの奨学金のソリューションをソートはじめに

第4章/における「情報オリンピックパス、」演習:のために書かれた羅区P1093

タイトル説明

小学校は最近、トップ5の学生の奨学金の学術の卓越性の一部として思い付くするつもりスポンサーの合計を、受け取りました。言語、数学、英語:期間は、各学生は、3コースの実績を持っています。ハイからローへの整理を押して、二人の学生であれば、同じスコア、降順で、言語スコア、2つの学生スコアと言語スコアは、その後、学生の数が少ないの規定は、学校の前に立って、同じであれば、そう、各学生を注文すると、一意に決定されます。
タスクは:第一上記の規則を並び替え、入力3コースの結果に基づいて総合スコアを算出し、そして、学校の数と総スコアの順位の最終的な出力順序上位5つの学生。あなたは上記の規則に厳密に従ってソートされなければならないので、前の5人の学生に、奨学金は、誰にとっても同じではないことに注意してください。例えば、一つの正解で、出力データの最初の二行であれば(出力2つの数の各行:学校、スコア)である:
\(7 \) \(279 \)
\(5 \) \(279 \)
データの2行の意味は以下のとおりです。2人の生徒が続く学校の数が最も多い得点\(7 \)番号、\(5 \)番号を。2人の生徒が外である\(279 \) スコアが入力言語、数学、英語と3人の被験者に等しい)が、学生数は\(7 \)高い生徒の言語能力。あなたの上の2つの出力データがある場合:
\(5 \) \(279 \)
\(7 \) \(279 \)
を押して出力エラー処理、得点することはできません。

入力形式

共同\(N + 1 \)ライン。
\(1 \)正の整数行う\(N-(N-LE \ル300 \ 5は)\) 学生の数は、学校の選択に関与表します。
\(2 \)\(N + 1 \)行を有する各列\(3 \)スペースで区切られた数字は、各番号\(0 \)のために(100 \)を\の間。最初の\(J \)ライン\(3 \)学生IDを示す数字順次れる(J-1 \)\生徒の学力言語、数学、英語の。各学校の番号入力順序番号の学生\(1 \) \(N- \) 入力行数を引いデータ起こる\(1 \を))。
与えられたデータが正しいか、テストしていません。

出力フォーマット

5行の合計は、各ラインは、学校の数と総得点の前に55人の学生のために、それぞれ、2つの正の整数のスペースで区切られています。

サンプル入力

6
90 67 80
87 66 91
78 89 91
88 99 77
67 89 64
78 89 98

サンプル出力

6 265
4 264
3 258
2 244
1 237

分析

この質問は、グループの人気の最初のNOIP 2017準決勝で\(1 \)タイトル。
アイデアは達成することである:構造がソート。
私たちは、名前の開くことができるStudent構造体の配列を初期化中に数と英語の勉強3人の被験者の数を含め、構造、および構造体の定義で:

struct Student {
    int id; // 学号
    int x;  // 语文成绩
    int y;  // 数学成绩
    int z;  // 英语成绩
} a[303];

その後、我々は次のように、対応する比較関数を書く、ゲームのルールを分析します:

#include <bits/stdc++.h>
using namespace std;
struct Student {
    int id, x, y, z; // 分别表示学号、语数英成绩
} a[303];
int n;
bool cmp(Student a, Student b) {
    if (a.x+a.y+a.z != b.x+b.y+b.z) // 如果总分不一样
        return a.x+a.y+a.z > b.x+b.y+b.z;   // 按总分从高到低排序
    if (a.x != b.x)     // 如果语文成绩不一样
        return a.x > b.x;   // 按语文成绩从高到低排序
    // 如果总分和语文成绩都相同,按照学号从小到大排序
    return a.id < b.id;
}
int main() {
    cin >> n;
    for (int i = 1; i <= n; i ++) {
        a[i].id = i;    // 首先为第i位同学赋予学号i
        cin >> a[i].x >> a[i].y >> a[i].z; // 然后输入他的语数英成绩
    }
    sort(a+1, a+1+n, cmp);
    for (int i = 1; i <= 5; i ++)   // 输出前5名的学号和总分
        cout << a[i].id << " " << a[i].x+a[i].y+a[i].z << endl;
    return 0;
}

おすすめ

転載: www.cnblogs.com/zifeiynoip/p/11450514.html