B1095 解码PAT准考证

题目链接:https://pintia.cn/problem-sets/994805260223102976/problems/1071786104348536832

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

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

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

输入格式:

输入首先在一行中给出两个正整数 N(≤)和 M(≤),分别为考生人数和统计要求的个数。

接下来 N 行,每行给出一个考生的准考证号和其分数(在区间 [ 内的整数),其间以空格分隔。

考生信息之后,再给出 M 行,每行给出一个统计要求,格式为:类型 指令,其中

  • 类型 为 1 表示要求按分数非升序输出某个指定级别的考生的成绩,对应的 指令 则给出代表指定级别的字母;
  • 类型 为 2 表示要求将某指定考场的考生人数和总分统计输出,对应的 指令 则给出指定考场的编号;
  • 类型 为 3 表示要求将某指定日期的考生人数分考场统计输出,对应的 指令 则给出指定日期,格式与准考证上日期相同。

输出格式:

对每项统计要求,首先在一行中输出 Case #: 要求,其中 # 是该项要求的编号,从 1 开始;要求 即复制输入给出的要求。随后输出相应的统计结果:

  • 类型 为 1 的指令,输出格式与输入的考生信息格式相同,即 准考证号 成绩。对于分数并列的考生,按其准考证号的字典序递增输出(题目保证无重复准考证号);
  • 类型 为 2 的指令,按 人数 总分 的格式输出;
  • 类型 为 3 的指令,输出按人数非递增顺序,格式为 考场编号 总人数。若人数并列则按考场编号递增顺序输出。

如果查询结果为空,则输出 NA

输入样例:

8 4
B123180908127 99
B102180908003 86
A112180318002 98
T107150310127 62
A107180908108 100
T123180908010 78
B112160918035 88
A107180908021 98
1 A
2 107
3 180908
2 999

输出样例:

Case 1: 1 A
A107180908108 100
A107180908021 98
A112180318002 98
Case 2: 2 107
3 260
Case 3: 3 180908
107 2
123 2
102 1
Case 4: 2 999
NA

最终AC代码如下:
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <unordered_map>
#include <algorithm>
using namespace std;

bool cmp(pair<string, int> p1, pair<string, int> p2)
{
    if(p1.second != p2.second) {
        return p1.second > p2.second;
    } else {
        return p1.first < p2.first;
    }
}

int main()
{
    int i, n, m, t;
    string s;
    vector<pair<string, int> > vp;
    vector<pair<string, int> >::iterator it;
    scanf("%d %d", &n, &m);
    for(i=0; i<n; i++) {
        cin>>s;
        scanf("%d", &t);
        vp.push_back(make_pair(s, t));
    }
    for(i=0; i<m; i++) {
        scanf("%d", &t);
        cin>>s;
        printf("Case %d: %d %s\n", i+1, t, s.c_str());
        if(t==1) {
            vector<pair<string, int> > ans;
            for(it=vp.begin(); it!=vp.end(); it++) {
                if(((*it).first)[0] == s[0]) {
                    ans.push_back(*it);
                }
            }
            if(ans.size()==0) {
                printf("NA\n");
            } else {
                sort(ans.begin(), ans.end(), cmp);
                for(it=ans.begin(); it!=ans.end(); it++) {
                    printf("%s %d\n", ((*it).first).c_str(), (*it).second);
                }
            }
        }else if(t==2){
            int num=0, sum=0;
            string str;
            for(it=vp.begin(); it!=vp.end(); it++) {
                str = ((*it).first).substr(1, 3);
                if(str == s) {
                    num++;
                    sum += (*it).second;
                }
            }
            if(num==0){
                printf("NA\n");
            }else{
                printf("%d %d\n", num, sum);
            }
        }else if(t==3){
            unordered_map<string, int> mp;
            string str, temp;
            for(it=vp.begin(); it!=vp.end(); it++) {
                str = ((*it).first).substr(4, 6);
                if(str == s) {
                    mp[((*it).first).substr(1, 3)]++;
                }
            }
            if(mp.size()==0){
                printf("NA\n");
            }else{
                vector<pair<string, int> > ans;
                for(auto mit:mp){
                    ans.push_back({mit.first,mit.second});
                }
                sort(ans.begin(), ans.end(), cmp);
                for(it=ans.begin(); it!=ans.end(); it++) {
                    printf("%s %d\n", ((*it).first).c_str(), (*it).second);
                }
            }
        }else{
            printf("NA\n");
        }
    }
    return 0;
}

提示(主要注意两个地方):

一、除string类型的变量,其余变量的输入输出均用scanf、printf方式。

二、t==3时,必须使用unordered_map存储考场号和对应的次数,且对其遍历时对应采用以下方式:

for(auto mit:mp){
    ans.push_back({mit.first,mit.second});
}        

不要问为什么?因为不注意一,测试用例2、3极容易超时;不注意二,测试用例2还是出现超时。因此本题最大的难度在于对时间复杂度的把握,测试用例本身并不存在什么细小的坑点。

此外,以下几行代码也需注意(虽然之前记录过):

if(str == s) {
    mp[((*it).first).substr(1, 3)]++;
}

我把一般情况的逻辑对应的代码粘贴如下:一对比,就会知道妙处所在了。

if(str == s) {
    string temp = ((*it).first).substr(1, 3);
    map<string, int>::iterator mit = mp.find(temp);
    if(mit!=mp.end()){
        mit->second++;
    }else{
            mp[temp] = 1;
    }
}    

是不是感觉简洁太多了!!!

由于我使用的DevC++不支持unordered_map的使用(版本太低了),因此之前一直在尝试寻找不使用unordered_map的方法,可惜没有找到。某位大佬倒是只用map就AC了,而且速度极快。由于其代码在我本地环境运行不了,所以没对其代码进行深入的研究,记录其链接如下:https://blog.csdn.net/qdv1100/article/details/84977594

原文地址:https://www.cnblogs.com/heyour/p/12248583.html

时间: 2024-11-02 16:20:47

B1095 解码PAT准考证的相关文章

PAT B1095 解码PAT准考证

半个月了,每天做几道题PAT基础题,终于把基础的95道题目做完了.总体来说,没有太难的东西,偶尔几个题目有点复杂而已. 加油,离3月份的考试越来越近了,还有155道题目等着我呢!!! B_1095题目如下: 1095 解码PAT准考证 (25 分) PAT 准考证号由 4 部分组成: 第 1 位是级别,即 T 代表顶级:A 代表甲级:B 代表乙级: 第 2~4 位是考场编号,范围从 101 到 999: 第 5~10 位是考试日期,格式为年.月.日顺次各占 2 位: 最后 11~13 位是考生编

PTA乙级 (*1095 解码PAT准考证 (25分))

1095 解码PAT准考证 (25分) https://pintia.cn/problem-sets/994805260223102976/problems/1071786104348536832 题目大意:给出一组学生的准考证号和成绩,准考证号包含了等级(乙甲顶),考场号,日期,和个人编号信息,并有三种查询方式查询一:给出考试等级,找出该等级的考生,按照成绩降序,准考证升序排序查询二:给出考场号,统计该考场的考生数量和总得分查询三:给出考试日期,查询改日期下所有考场的考试人数,按照人数降序,考

乙级 1095 解码PAT准考证

PAT 准考证号由 4 部分组成: 第 1 位是级别,即 T 代表顶级:A 代表甲级:B 代表乙级: 第 2~4 位是考场编号,范围从 101 到 999: 第 5~10 位是考试日期,格式为年.月.日顺次各占 2 位: 最后 11~13 位是考生编号,范围从 000 到 999. 现给定一系列考生的准考证号和他们的成绩,请你按照要求输出各种统计信息. 输入格式: 输入首先在一行中给出两个正整数 N(≤)和 M(≤),分别为考生人数和统计要求的个数. 接下来 N 行,每行给出一个考生的准考证号和

PAT Basic 1095 解码PAT准考证 (25 分)

PAT 准考证号由 4 部分组成: 第 1 位是级别,即 T 代表顶级:A 代表甲级:B 代表乙级: 第 2~4 位是考场编号,范围从 101 到 999: 第 5~10 位是考试日期,格式为年.月.日顺次各占 2 位: 最后 11~13 位是考生编号,范围从 000 到 999. 现给定一系列考生的准考证号和他们的成绩,请你按照要求输出各种统计信息. 输入格式: 输入首先在一行中给出两个正整数 N(≤)和 M(≤),分别为考生人数和统计要求的个数. 接下来 N 行,每行给出一个考生的准考证号和

1095 解码PAT准考证

麻烦的一批!!!还好题目比较耿直,按要求输出即可,超时就换unordered_map. 新学了小玩意STL-pair,可以理解成一个结构体. struct pair{ typename1 first; typename2 second; }; 用途: 1.可以代替二元结构体及其构造函数,节省编码时间.类似 B1085 PAT单位排行. 2.可以作为map的键值对来进行插入. 1 #include"iostream" 2 #include"algorithm" 3 #

PTA乙级1091-1095

1091 N-自守数 (15 分) 如果某个数 K 的平方乘以 N 以后,结果的末尾几位数等于 K,那么就称这个数为“N-自守数”.例如 3,而 2 的末尾两位正好是 9,所以 9 是一个 3-自守数. 本题就请你编写程序判断一个给定的数字是否关于某个 N 是 N-自守数. 输入格式: 输入在第一行中给出正整数 M(≤),随后一行给出 M 个待检测的.不超过 1000 的正整数. 输出格式: 对每个需要检测的数字,如果它是 N-自守数就在一行中输出最小的 N 和 NK?2?? 的值,以一个空格隔

TS数据流PAT和PMT分析

TS流,是基于packet的位流格式,每个packet是188个字节或者204个字节(一般是188字节,204字节格式是在188字节的packet后面加上16字节的CRC数据,其他格式相同),解析TS流,先解析每个packet ,然后从一个packet中,解析出PAT的PID,根据PID找到PAT包,然后从PAT包中解析出PMT的PID,根据PID找到PMT包,在从PMT包中解析出Video和Audio(也有的包括Teletext和EPG)的PID.然后根据PID找出相应的包. 所有packet

PAT 1041. 考试座位号(15)

每个PAT考生在参加考试时都会被分配两个座位号,一个是试机座位,一个是考试座位.正常情况下,考生在入场时先得到试机座位号码,入座进入试机状态后,系统会显示该考生的考试座位号码,考试时考生需要换到考试座位就座.但有些考生迟到了,试机已经结束,他们只能拿着领到的试机座位号码求助于你,从后台查出他们的考试座位号码. 输入格式: 输入第一行给出一个正整数N(<=1000),随后N行,每行给出一个考生的信息:"准考证号 试机座位号 考试座位号".其中准考证号由14位数字组成,座位从1到N编

PAT(A) 1075. PAT Judge (25)

The ranklist of PAT is generated from the status list, which shows the scores of the submittions. This time you are supposed to generate the ranklist for PAT. Input Specification: Each input file contains one test case. For each case, the first line