PTA乙级 (*1095 解码PAT准考证 (25分))
1095 解码PAT准考证 (25分)
https://pintia.cn/problem-sets/994805260223102976/problems/1071786104348536832
题目大意:给出一组学生的准考证号和成绩,准考证号包含了等级(乙甲顶),考场号,日期,和个人编号信息,并有三种查询方式
查询一:给出考试等级,找出该等级的考生,按照成绩降序,准考证升序排序
查询二:给出考场号,统计该考场的考生数量和总得分
查询三:给出考试日期,查询改日期下所有考场的考试人数,按照人数降序,考场号升序排序
分析:先把所有考生的准考证和分数记录下来
1.按照等级查询,枚举选取匹配的学生,然后排序即可
2.按照考场查询,枚举选取匹配的学生,然后计数、求和
3.按日期查询每个考场人数,用unordered_map存储,最后排序汇总
注意:1.第三个用map存储会超时,用unordered_map就不会超时
2.排序传参建议用引用传参,这样更快
#include <iostream>
#include <algorithm>
#include <vector>
#include <unordered_map>
using namespace std;
struct node{
string t;
int value;
};
bool cmp(const node &a,const node &b)
{
return a.value!=b.value?a.value>b.value:a.t<b.t;
}
int main()
{
int n,m,num;
string s;
cin>>n>>m;
vector<node> vec(n);
for(int i=0;i<n;i++) cin>>vec[i].t>>vec[i].value;
for(int i=1;i<=m;i++)
{
cin>>num>>s;
printf("Case %d: %d %s\n",i,num,s.c_str());
vector<node> ans;
int cnt=0,sum=0;
if(num==1){
for(int j=0;j<n;j++)
if(vec[j].t[0]==s[0]) ans.push_back(vec[j]);
}else if(num==2){
for(int j=0;j<n;j++)
if(vec[j].t.substr(1,3)==s){
cnt++;
sum+=vec[j].value;
}
if(cnt!=0) printf("%d %d\n",cnt,sum);
}else if(num==3){
unordered_map<string,int> mp;
for(int j=0;j<n;j++)
if(vec[j].t.substr(4,6)==s) mp[vec[j].t.substr(1,3)]++;
for(auto it:mp) ans.push_back({it.first,it.second});
}
sort(ans.begin(),ans.end(),cmp);
for(int j=0;j<ans.size();j++) printf("%s %d\n",ans[j].t.c_str(),ans[j].value);
if((num==1||num==3)&&ans.size()==0||(num==2&&cnt==0)) printf("NA\n");
}
return 0;
}
值得注意的是:
map本身默认对key排序,但我们不需要。
我们想对map的value排序。故实际代码中用unordered_map,它是非排序版,比map快许多。
对map(或unordered_map)的value排序:
把map的key & value存到vector中,用sort对vector排序,这种方法一定要学会。
注:mp是map,ans是vector。
for(auto it : mp)
ans.push_back({it.first, it.second});
sort(ans.begin(), ans.end(), cmp);
天晴了,起飞吧

浙公网安备 33010602011771号