标签:c代码 部分 -- set mat icon name 测试用例 blog
题目链接:https://pintia.cn/problem-sets/994805260223102976/problems/1071786104348536832
PAT 准考证号由 4 部分组成:
T
代表顶级;A
代表甲级;B
代表乙级;现给定一系列考生的准考证号和他们的成绩,请你按照要求输出各种统计信息。
输入首先在一行中给出两个正整数 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。
标签:c代码 部分 -- set mat icon name 测试用例 blog
原文地址:https://www.cnblogs.com/heyour/p/12248583.html