PAT-A 1153 Decode Registration Card of PAT 题解
之前自己写的傻逼代码:
(为了节省大家的时间,大家可以不用看了,纯粹为了记录自己的傻逼行为)
#include<iostream>
#include<string>
#include<cstring>
#include<set>
#include<algorithm>
#include<vector>
#include<unordered_map>
using namespace std;
const int MAX_N = 10010;
int n,m,k,t;
struct Student
{
string id;
int score;
}s[MAX_N];
unordered_map<string,set<int> > date_mapping;//根据日期映射
//用于指示考场的相关信息。
struct Site{
int stu_cnt;
int total_score;
int num;//用于标记考场的编号
}site[1010];
bool cmp(const Student &stu1,const Student &stu2){
if(stu1.score != stu2.score){
return stu1.score > stu2.score;
}
else{
return stu1.id<stu2.id;
}
}
int str_to_int(const string &str){
int ans= 0 ;
for(int i = 0;i<str.length();i++)
{
ans = ans * 10 + str[i]-'0';
}
return ans;
}
void q1(char level){
vector<Student> list;
for(int i = 0;i<n;i++){
if(s[i].id[0] == level){
list.push_back(s[i]);
}
}
printf("Case %d: %d %c\n",k,t,level);
if(list.size() == 0){
cout<<"NA"<<endl;
return;
}
sort(list.begin(),list.end(),cmp);
for(int i = 0;i<list.size();i++){
cout<<list[i].id<<" "<<list[i].score<<endl;
}
}
void q2(int site_num){
printf("Case %d: %d %d\n",k,t,site_num);
if(site[site_num].stu_cnt){
cout<<site[site_num].stu_cnt<<" "<<site[site_num].total_score<<endl;
}
else {
cout<<"NA"<<endl;
}
}
bool cmp_site(const Site &s1,const Site &s2)
{
if(s1.stu_cnt != s2.stu_cnt){
return s1.stu_cnt>s2.stu_cnt;
}
else{
return s1.num<s2.num;
}
}
void q3(string date){
printf("Case %d: %d ",k,t);
cout<<date<<endl;
if(date_mapping[date].size() == 0){
cout<<"NA"<<endl;return;
}
vector<Site> vec;
for(set<int>::iterator it = date_mapping[date].begin();it!=date_mapping[date].end();it++){
vec.push_back(site[*it]);
}
sort(vec.begin(),vec.end(),cmp_site);
for(int i = 0;i<vec.size();i++){
cout<<vec[i].num<<" "<<vec[i].stu_cnt<<endl;
}
return;
}
int main(){
cin>>n>>m;
for(int i =0;i<n;i++){
cin>>s[i].id>>s[i].score;
int site_num = str_to_int(s[i].id.substr(1,3));
//根据考场编号来把相应的数据做调整。
site[site_num].stu_cnt ++;site[site_num].total_score += s[i].score;
site[site_num].num = site_num;
string date = s[i].id.substr(4,6);
//把相应的考场编号推入
date_mapping[date].insert(site_num);
}
while (m--)
{
++k;
cin>>t;
string temp_date;
switch (t)
{
case 1:
char level;cin>>level;
q1(level);
break;
case 2:
int site_num;
cin>>site_num;
q2(site_num);
break;
case 3:
cin>>temp_date;
q3(temp_date);
break;
default:
break;
}
}
return 0;
}
优化后的代码:
#include<iostream>
#include<string>
#include<cstring>
#include<set>
#include<map>
#include<algorithm>
#include<vector>
#include<unordered_map>
using namespace std;
int n,m,k,t;
string q;
//建立一个通用化的数据结构
struct node
{
string id;
int val;
};
bool cmp(const node &n1,const node &n2){
return n1.val != n2.val ? n1.val > n2.val : n1.id < n2.id;
}
int main(){
scanf("%d%d",&n,&m);//n表示考生的数量、m表示查询记录的数目
vector<node> list(n);//list用于存储考生的相关信息
for(int i = 0;i<n;i++){//读取list的所有内容。
cin>>list[i].id>>list[i].val;
}
for(int case_num = 1;case_num <= m;case_num ++){
cin>>t>>q; //t表示查询的类型,q表示查询的具体内容
printf("Case %d: %d %s\n",case_num,t,q.c_str());//把q转为c类型的指针。这样能够加快打印速度。
vector<node> ans;//可以把最后返回的结果都堪称通用的数据结构
if(t == 1){
for(int i = 0;i<n;i++){
if(list[i].id[0] == q[0]){
ans.push_back(list[i]);
}
}
}
else if(t == 2){
//如果查询出来的结果产生了问题,就跳转到最后的地方去处理。
int cnt = 0 , total_val = 0;
for(int i = 0;i<n;i++){
if(list[i].id.substr(1,3) == q){
cnt++;total_val += list[i].val;
}
}
//由于我们很清楚的知道,这里只有一行数据需要打印,所以不用再加入到ans列表中了。
if(cnt) {printf("%d %d\n",cnt,total_val);continue;}
}
else if(t == 3)
{
//这里我们要通过日期做映射操作。
unordered_map<string,int> mp;
for(int i = 0;i<n;i++){
string date = list[i].id.substr(4,6);
if(date == q){
mp[list[i].id.substr(1,3)]++;
}
}
//柳神的代码这个写的真的非常棒!开拓了自己的新思路
for(auto item : mp){
ans.push_back({item.first,item.second});
}
}
sort(ans.begin(),ans.end(),cmp);//排序
for(int i = 0;i<ans.size();i++){
printf("%s %d\n",ans[i].id.c_str(),ans[i].val);
}
if(((t == 1 || t == 3) && ans.size() == 0) || (t == 2)){
printf("NA\n");
}
}
return 0;
}
以上代码是我加上注释之后的。大部分和柳神写的题解差不多。顺便贴上柳神的博客:
柳婼
慢慢地也从柳神的题解中感悟到了她的PAT题解代码风格。PAT的题目经常有这种不同的查询方式,我们常规的思维都是如果是第一种查询方式,用什么函数,第二种用什么…………柳神的思路是找出这些查询过程的共同点,然后提取这些共同点写成代码。这也体现出了计算机科学的一个非常重要的思想:自动化!一旦某种重复性工作超过了15分钟,那我们就可以想方法探索出这种重复性工作里的通用工作方式,然后交给计算机来完成!