PAT-A 1153 Decode Registration Card of PAT 题解

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分钟,那我们就可以想方法探索出这种重复性工作里的通用工作方式,然后交给计算机来完成!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值