Skip to content

Latest commit

 

History

History
83 lines (70 loc) · 3.86 KB

1153. Decode Registration Card of PAT.md

File metadata and controls

83 lines (70 loc) · 3.86 KB

【PAT A-1153、PAT B-1095】Decode Registration Card of PAT、解码 PAT 准考证

题意概述

PAT 准考证号由 4 部分组成:

  • 第 1 位是级别,即 T 代表顶级;A 代表甲级;B 代表乙级;
  • 第 2~4 位是考场编号,范围从 101 到 999;
  • 第 5~10 位是考试日期,格式为年、月、日顺次各占 2 位;
  • 最后 11~13 位是考生编号,范围从 000 到 999。

现给定一系列考生的准考证号和他们的成绩,请你按照要求输出各种统计信息。

输入输出格式

输入首先在一行中给出两个正整数 N 和 M,分别为考生人数和统计要求的个数。接下来 N 行,每行给出一个考生的准考证号和其分数(在区间[0,100]内的整数),其间以空格分隔。考生信息之后,再给出 M 行,每行给出一个统计要求,格式为:类型 指令,其中:

  • 类型为 1 表示要求按分数非升序输出某个指定级别的考生的成绩,对应的指令则给出代表指定级别的字母;
  • 类型为 2 表示要求将某指定考场的考生人数和总分统计输出,对应的指令则给出指定考场的编号;
  • 类型为 3 表示要求将某指定日期的考生人数分考场统计输出,对应的指令则给出指定日期,格式与准考证上日期相同。 对每项统计要求,首先在一行中输出Case #: 要求,其中#是该项要求的编号,从 1 开始;要求即复制输入给出的要求。随后输出相应的统计结果:
  • 类型为 1 的指令,输出格式与输入的考生信息格式相同,即准考证号 成绩。对于分数并列的考生,按其准考证号的字典序递增输出(题目保证无重复准考证号);
  • 类型为 2 的指令,按人数 总分的格式输出;
  • 类型为 3 的指令,输出按人数非递增顺序,格式为“考场编号 总人数”。若人数并列则按考场编号递增顺序输出。 如果查询结果为空,则输出NA

数据规模

$$N\le{10}^4,M\le 100$$

算法设计

使用好 pair、vector、unordered_map 和 sort 即可解决本题。

C++代码

#include <bits/stdc++.h>
using namespace std;
using gg = long long;
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    using psg = pair<string, gg>;
    //存储T、A、B级别下的考生,处理类型1的要求
    unordered_map<char, vector<psg>> c1;
    //存储考场中的人数和总分,处理类型2的要求
    unordered_map<string, array<gg, 2>> c2;
    //存储日期下考场中的人数,处理类型3的要求
    unordered_map<string, unordered_map<string, gg>> c3;
    gg ni, mi, ci, score;
    string si;
    cin >> ni >> mi;
    for (gg i = 0; i < ni; ++i) {  //读取准考证和成绩
        cin >> si >> score;
        c1[si[0]].push_back({si, score});  //将该考生插入到对应级别中
        auto& p = c2[si.substr(1, 3)];
        ++p[0];  //递增考场人数
        p[1] += score;  //更新考场总分
        ++c3[si.substr(4, 6)][si.substr(1, 3)];  //递增日期、考场中的人数
    }
    auto cmp = [](const psg& s1, const psg& s2) {  //比较函数
        return tie(s2.second, s1.first) < tie(s1.second, s2.first);
    };
    for (gg i = 1; i <= mi; ++i) {
        cin >> ci >> si;
        cout << "Case " << i << ": " << ci << " " << si << "\n";
        if ((ci == 1 and c1.count(si[0])) or (ci == 3 and c3.count(si))) {
            auto v = ci == 1 ? c1[si[0]] : vector<psg>(c3[si].begin(), c3[si].end());
            //排序,注意类型1和类型3的比较函数是一样的
            sort(v.begin(), v.end(), cmp);
            for (auto& j : v) {
                cout << j.first << " " << j.second << "\n";
            }
        } else if (ci == 2 and c2.count(si)) {
            cout << c2[si][0] << " " << c2[si][1] << "\n";
        } else {
            cout << "NA\n";
        }
    }
    return 0;
}