PAT 准考证号由 4 部分组成:
第 1 位是级别,即 T 代表顶级;A 代表甲级;B 代表乙级;
第 2~4 位是考场编号,范围从 101 到 999;
第 5~10 位是考试日期,格式为年、月、日顺次各占 2 位;
最后 11~13 位是考生编号,范围从 000 到 999。
现给定一系列考生的准考证号和他们的成绩,请你按照要求输出各种统计信息。
输入格式:
输入首先在一行中给出两个正整数 N(≤104 )和 M(≤100),分别为考生人数和统计要求的个数。
接下来 N 行,每行给出一个考生的准考证号和其分数(在区间 [0,100] 内的整数),其间以空格分隔。
考生信息之后,再给出 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
亮点:
- 对自定义vector的使用与自定义vector的排序;
- 对map关联容器的排序与map关联容器的访问;
- 用sort进行排序等;
- 将c++的string类 转化成字符数组的形式用printf输出;
因为之前再用c++的stl库,所以遇到这种题都往stl方面想:
大致思路都是将数据存到结构体里,每次遇到 1,2,3种情况,在相应的结构体里找到需要用的信息,然后存放的vector或者map中、然后用sort进行排序;主要难点就是如何对自定义vecotr容器进行排序,还有map键值对进行排序;
因为sort只能对容器进行排序,比如vector、list等,所以在对map排序的情况下可以将map放入vector中,然后自定义vector的排序规则,然后对vector进行排序:
这里要对map关联容器排序的话,如果对key值进行排序,只需要自定义规则,写入定义的map即可,例如: map<string,int,cmp>m; m容器会按照cmp规则排序;
如果要对value进行排序,就必须要重载operator方法,写进类里面,然后进行排序;
刚开始做的时候有两个运行超时,源码如下:
#include<bits/stdc++.h>
using namespace std;
struct infor
{
string id;
int grade;
}stu[10000];
bool cmp1(infor p1,infor p2)
{
if(p1.grade!=p2.grade)
return p1.grade > p2.grade;
else
return p1.id<p2.id;
}
struct cmp2
{
bool operator()(pair<string,int> &p1,pair<string,int> &p2)
{
if(p1.second==p2.second)
return p1.first<p2.first;
else
return p1.second>p2.second;
}
};
int main()
{
int M,N;
cin>>M>>N; //8 4
for(int i=0;i<M;i++)
{
cin>>stu[i].id>>stu[i].grade;
}
for(int i=0;i<N;i++)
{
int x;
cin>>x;
if(x==1)
{
char op;
vector<infor>v;
vector<infor>::iterator it;
int flag=0;
cin>>op;
for(int j=0;j<M;j++)
{
if(stu[j].id[0]==op)
{
flag=1;
v.push_back(stu[j]);
}
}
sort(v.begin(),v.end(),cmp1);
printf("Case %d: 1 %c\n",i+1,op);
if(flag==1)
{
for(it=v.begin();it!=v.end();it++)
cout<<it->id<<" "<<it->grade<<endl;
v.clear();
}
else
printf("NA\n");
}
if(x==2)
{
int sum=0,count=0,flag=0;
string kao;
cin>>kao;
printf("Case %d: 2 ",i+1);
cout<<kao<<endl;
for(int j=0;j<M;j++)
{
string nn=(stu[j].id).substr(1,3);
if(nn==kao)
{
flag=1;
count++;
sum=sum+stu[j].grade;
}
}
if(flag==1)
cout<<count<<" "<<sum<<endl;
else
printf("NA\n");
}
if(x==3)
{
string kao;
int flag=0;
map<string,int>m;
cin>>kao;
printf("Case %d: 3 ",i+1);
cout<<kao<<endl;
for(int j=0;j<M;j++)
{
if(kao==(stu[j].id).substr(4,6))
{
flag=1;
m[(stu[j].id).substr(1,3)]++;
}
}
if(flag==1)
{
vector<pair<string,int> >v1(m.begin(),m.end());
vector<pair<string,int> >::iterator it1;
sort(v1.begin(),v1.end(),cmp2());
for(it1=v1.begin();it1!=v1.end();++it1)
{
cout<<it1->first<<" "<<it1->second<<endl;
}
v1.clear();
}
else
printf("NA\n");
}
}
return 0;
}
这段代码提交后有两个运行超时,然后很神奇的是,如果将里面的cout 换成 printf.....最最最最最神奇的来了,代码全部AC,后面查了一下,printf的运行速度要是cout的三倍左右,这个就很想不通,c++特有的cout,cin,还能出现运行超时,这个测试点也很恶心;谁能想到运行超时尽然不是优化代码的问题;
后面附AC代码:
(用printf 替换的 cout 对比我用注释出来了);
#include<bits/stdc++.h>
using namespace std;
struct infor
{
string id;
int grade;
}stu[10000];
bool cmp1(infor p1,infor p2)
{
if(p1.grade!=p2.grade)
return p1.grade > p2.grade;
else
return p1.id<p2.id;
}
struct cmp2
{
bool operator()(pair<string,int> &p1,pair<string,int> &p2)
{
if(p1.second==p2.second)
return p1.first<p2.first;
else
return p1.second>p2.second;
}
};
int main()
{
int M,N;
cin>>M>>N; //8 4
for(int i=0;i<M;i++)
{
cin>>stu[i].id>>stu[i].grade;
}
for(int i=0;i<N;i++)
{
int x;
cin>>x;
if(x==1)
{
char op;
vector<infor>v;
vector<infor>::iterator it;
int flag=0;
cin>>op;
for(int j=0;j<M;j++)
{
if(stu[j].id[0]==op)
{
flag=1;
v.push_back(stu[j]);
}
}
sort(v.begin(),v.end(),cmp1);
printf("Case %d: 1 %c\n",i+1,op);
if(flag==1)
{
for(it=v.begin();it!=v.end();it++)
{
printf("%s %d\n",(it->id).c_str(),it->grade);
}
// cout<<it->id<<" "<<it->grade<<endl;
v.clear();
}
else
printf("NA\n");
}
if(x==2)
{
int sum=0,count=0,flag=0;
string kao;
cin>>kao;
printf("Case %d: 2 ",i+1);
cout<<kao<<endl;
for(int j=0;j<M;j++)
{
string nn=(stu[j].id).substr(1,3);
if(nn==kao)
{
flag=1;
count++;
sum=sum+stu[j].grade;
}
}
if(flag==1)
printf("%d %d\n",count,sum);
// cout<<count<<" "<<sum<<endl;
else
printf("NA\n");
}
if(x==3)
{
string kao;
int flag=0;
map<string,int>m;
cin>>kao;
printf("Case %d: 3 ",i+1);
cout<<kao<<endl;
for(int j=0;j<M;j++)
{
if(kao==(stu[j].id).substr(4,6))
{
flag=1;
m[(stu[j].id).substr(1,3)]++;
}
}
if(flag==1)
{
vector<pair<string,int> >v1(m.begin(),m.end());
vector<pair<string,int> >::iterator it1;
sort(v1.begin(),v1.end(),cmp2());
for(it1=v1.begin();it1!=v1.end();++it1)
{
printf("%s %d\n",(it1->first).c_str(), it1->second);
// cout<<it1->first<<" "<<it1->second<<endl;
}
v1.clear();
}
else
printf("NA\n");
}
}
return 0;
}
总的来说,这篇文章对stl的应用帮助很大,有自定义的vector与自定义vector的排序,还有map的排序(存放到vector);