PAT A1153 Decode Registration Card of PAT

26 篇文章 0 订阅

题目描述

1153 Decode Registration Card of PAT (25分)

知识点

STL的使用,排序

实现

码前思考

  1. 大型模拟题
  2. 针对每一种情况,我都使用了一个容器存储结果,这样查询的时候就可以直接查询了。
//究极模拟题
//注意判空 
#include "bits/stdc++.h"
using namespace std;

int n;
int m;

struct node{
	string id;
	int score;
	node(){};
	node(string _id,int _score):id(_id),score(_score){}
};

struct dot{
	int site;
	int number;
	dot(){};
	dot(int _site,int _number):site(_site),number(_number){}
};

unordered_map<char,int> c2n;
vector<node> level[3];
unordered_map<int,int> case21;
unordered_map<int,int> case22;
unordered_map<int,unordered_map<int,dot>> case3; 
bool isSort[3];

bool cmp1(node a,node b){
	return a.score == b.score ? a.id<b.id : a.score > b.score;
}

bool cmp2(dot a,dot b){
	return a.number == b.number ? a.site < b.site : a.number > b.number;
}

int main(){
	c2n['T'] = 0;
	c2n['A'] = 1;
	c2n['B'] = 2;
	fill(isSort,isSort+3,false);

	scanf("%d %d",&n,&m);
	for(int i=0;i<n;i++){
		string id;
		int score;
		cin>>id>>score;
		//首先是将其加入到某个考场中
		int l = c2n[id[0]];
		level[l].push_back(node(id,score));
		
		//然后是统计考点的分数和人数
		int site = stoi(id.substr(1,3)); 
		case21[site] += 1;
		case22[site] += score;
		
		//然后是统计某个时间某个考场的人
		int time = stoi(id.substr(4,6));
		//查看是否已经有这个考点了
		if(case3[time].count(site) == 0){
			case3[time][site] = dot(site,1);
		}else{
			case3[time][site].number++;
		} 
	} 
	
	//下面是进行查询
	for(int i=0;i<m;i++){
		int type;
		scanf("%d",&type);
		if(type == 1){
			char c;
			//注意空格? 
			scanf(" %c",&c);
			int l = c2n[c];
			printf("Case %d: %d %c\n",i+1,type,c);
			//输出这一个等级的所有成绩
			if(level[l].size()==0){
				printf("NA\n");
			}else{
				if(isSort[l] == false){
					sort(level[l].begin(),level[l].end(),cmp1);	
					isSort[l] = true;
				}
				for(int j=0;j<level[l].size();j++){
					cout<<level[l][j].id<<" "<<level[l][j].score<<endl;
				}
			}	
		}else if(type == 2){
			int site;
			scanf("%d",&site);
			printf("Case %d: %d %d\n",i+1,type,site);
			if(case21.count(site) == 0){
				printf("NA\n");
			}else{
				printf("%d ",case21[site]);
				printf("%d\n",case22[site]);
			}
		}else if(type == 3){
			int date;
			scanf("%d",&date);
			//注意前导0
			printf("Case %d: %d %06d\n",i+1,type,date);
			if(case3.count(date) == 0){
				printf("NA\n");
			}else{
				vector<dot> res;

				for(auto it2=case3[date].begin();it2!=case3[date].end();it2++){
					res.push_back(it2->second);
				}
				sort(res.begin(),res.end(),cmp2);
				for(int j=0;j<res.size();j++){
					printf("%d %d\n",res[j].site,res[j].number);
				}
			} 
		}
	} 
	return 0;
} 

码后反思

  1. 最后一个测试用例会超时,于是我对第一个测试用例加了一个判断,如果排序过了,下次就直接输出,然后就没超时了。。。
  2. 我看大神的代码简洁多了。。。如下:
    #include <iostream>
    #include <vector>
    #include <unordered_map>
    #include <algorithm>
    using namespace std;
    int N, M, choose;
    string tmp;
    pair<string, int> cards[11000];
    bool cmp(pair<string, int> p1, pair<string, int> p2) {
        return p1.second != p2.second ? p1.second > p2.second : p1.first < p2.first;
    }
    int main() {
        cin >> N >> M;
        for(int i = 0; i < N; i++)  
            cin >> cards[i].first >> cards[i].second;
        for(int c = 1; c <= M; c++) {
            cin >> choose >> tmp;
            printf("Case %d: %d %s\n", c, choose, tmp.c_str());
            if(choose == 1) {
                vector<pair<string, int>> v;
                for(int i = 0; i < N; i++) 
                    if(cards[i].first[0] == tmp[0]) v.push_back(cards[i]);
                if(v.size() != 0) {
                    sort(v.begin(), v.end(), cmp);
                    for(auto x : v) printf("%s %d\n", x.first.c_str(), x.second);
                } else printf("NA\n");
            } else if(choose == 2) {
                int cnt = 0, all_score = 0;
                for(int i = 0; i < N; i++) {
                    if(cards[i].first.substr(1, 3) == tmp) {
                        cnt++; 
                        all_score += cards[i].second;
                    }
                }
                if(cnt != 0) printf("%d %d\n", cnt, all_score);
                else printf("NA\n");
            }else {
                unordered_map<string, int> m;
                for(int i = 0; i < N; i++) 
                    if(cards[i].first.substr(4, 6) == tmp) 
                        m[cards[i].first.substr(1, 3)]++;
                if(m.size() != 0) {
                    vector<pair<string, int>> v(m.begin(), m.end());
                    sort(v.begin(), v.end(), cmp);
                    for(auto x: v) printf("%s %d\n", x.first.c_str(), x.second);
                } else printf("NA\n");
            }
        }
        return 0;
    }
    // B 123 180908 127
    // 1 decreasing
    // 2 Nt Ns
    // 3 Nnumber testee
    
    
    大神居然是每次查询都遍历所有的数据,居然没超时,很奇怪。。。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值