【PTA Advanced】1153 Decode Registration Card of PAT(C++)

本文介绍了PAT考试的注册卡格式,并提供了一种处理包含测试级别、考试地点、日期和考生编号的注册卡数据的方法。文章中给出了一个案例,涉及查询不同级别考生、特定考试地点的考生总数和分数,以及在特定日期各个考试地点的考生数量。通过示例输入和输出,展示了如何对这些查询进行统计和排序。
摘要由CSDN通过智能技术生成

目录

题目

Input Specification:

Output Specification:

Sample Input:

Sample Output:

思路

代码(又臭又长😞)


题目

A registration card number of PAT consists of 4 parts:

  • the 1st letter represents the test level, namely, T for the top level, A for advance and B for basic;
  • the 2nd - 4th digits are the test site number, ranged from 101 to 999;
  • the 5th - 10th digits give the test date, in the form of yymmdd;
  • finally the 11th - 13th digits are the testee's number, ranged from 000 to 999.

Now given a set of registration card numbers and the scores of the card owners, you are supposed to output the various statistics according to the given queries.

Input Specification:

Each input file contains one test case. For each case, the first line gives two positive integers N (≤104) and M (≤100), the numbers of cards and the queries, respectively.

Then N lines follow, each gives a card number and the owner's score (integer in [0,100]), separated by a space.

After the info of testees, there are M lines, each gives a query in the format Type Term, where

  • Type being 1 means to output all the testees on a given level, in non-increasing order of their scores. The corresponding Term will be the letter which specifies the level;
  • Type being 2 means to output the total number of testees together with their total scores in a given site. The corresponding Term will then be the site number;
  • Type being 3 means to output the total number of testees of every site for a given test date. The corresponding Term will then be the date, given in the same format as in the registration card.

Output Specification:

For each query, first print in a line Case #: input, where # is the index of the query case, starting from 1; and input is a copy of the corresponding input query. Then output as requested:

  • for a type 1 query, the output format is the same as in input, that is, CardNumber Score. If there is a tie of the scores, output in increasing alphabetical order of their card numbers (uniqueness of the card numbers is guaranteed);
  • for a type 2 query, output in the format Nt Ns where Nt is the total number of testees and Ns is their total score;
  • for a type 3 query, output in the format Site Nt where Site is the site number and Nt is the total number of testees at Site. The output must be in non-increasing order of Nt's, or in increasing order of site numbers if there is a tie of Nt.

If the result of a query is empty, simply print NA.

Sample Input:

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

Sample Output:

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

思路

难度评级:⭐️

我是一边输入card信息一边收集和统计数据,这样做的缺点在于很费时间和空间;

看了柳神的代码,才发现自己下面的代码“又臭又长”,心碎💔,指路柳神:PAT 1153 Decode Registration Card of PAT - 柳婼

柳神的做法是在输入query的时候开始统计数据,而且三种query用的是同一个vector,对vector的排序自定义cmp函数也是同一个,感觉非常巧妙

代码(又臭又长😞)

#include <iostream>
#include <unordered_map>
#include <vector>
#include <algorithm>

using namespace std;

struct Card {
	string number;
	int score;
}; 

struct Site {
	int num;
	int score;
};

struct Date {
	string site;
	int num;
};

unordered_map<char,vector<Card>> levelMap;
unordered_map<string,Site> siteMap;
unordered_map<string,unordered_map<string,int>> dateMap; 
vector<Date> dateVec; 
unordered_map<string,vector<Date>> dateVecMap;

bool cmpOfLevel(const Card &p1, const Card &p2) {
	return p1.score==p2.score ? p1.number<=p2.number : p1.score>p2.score;
}

bool cmpOfDate(const Date &p1, const Date &p2) {
	return p1.num==p2.num ? p1.site<=p2.site : p1.num>p2.num;
}

int main(int argc, char** argv) {
	int n,m;
	cin>>n>>m;
	
	for(int i=0;i<n;i++) {
		string cardNumber;
		int score;
		cin>>cardNumber>>score;
		Card card={cardNumber, score};
		
		// 将一个level的card收集起来 
		levelMap[cardNumber[0]].push_back(card);
		// 统计一个site下的card数和分数总和
		string site=cardNumber.substr(1,3);
		siteMap[site].num++;
		siteMap[site].score+=score;
		// 统计一个date下各site中的test数 
		string date=cardNumber.substr(4,6);
		if(dateMap[date].count(site)==0) {
			dateMap[date][site]=0;
		}
		dateMap[date][site]++;
	}
	
	// 对每个level的card排序,排序规则:先按照score倒序,score相同的按照number增序
	sort(levelMap['T'].begin(), levelMap['T'].end(), cmpOfLevel);
	sort(levelMap['A'].begin(), levelMap['A'].end(), cmpOfLevel);
	sort(levelMap['B'].begin(), levelMap['B'].end(), cmpOfLevel); 
	
	// 对dateMap的value进行排序,排序规则:先按照site内test数倒序,test数相同时按照site编号正序
	for(unordered_map<string,unordered_map<string,int>>::iterator it=dateMap.begin();it!=dateMap.end();it++) {
		// 将value转成vector
		dateVec.clear();
		unordered_map<string,int> sites=it->second;
		for(unordered_map<string,int>::iterator itt=sites.begin();itt!=sites.end();itt++) {
			Date date={itt->first,itt->second};
			dateVec.push_back(date);
		} 
		
		// 对vector排序
		sort(dateVec.begin(), dateVec.end(), cmpOfDate); 
		dateVecMap[it->first]=dateVec;
	} 
	
	for(int i=1;i<=m;i++) {
		int type;
		string term;
		cin>>type>>term;
		cout<<"Case "<<i<<": "<<type<<" "<<term<<endl; 
		switch(type) {
			case 1:
				if(levelMap[term[0]].size()==0) {
					cout<<"NA"<<endl;
					break;
				}
				for(Card card:levelMap[term[0]]) {
					cout<<card.number<<" "<<card.score<<endl;
				}
				break;
			case 2:
				if(siteMap[term].num==0) {
					cout<<"NA"<<endl;
					break;
				}
				cout<<siteMap[term].num<<" "<<siteMap[term].score<<endl;
				break;
			case 3:
				if(dateVecMap.count(term)==0) {
					cout<<"NA"<<endl;
					break;
				}
				vector<Date> vec=dateVecMap[term];
				for(Date date:vec) {
					cout<<date.site<<" "<<date.num<<endl;
				}
				break;
		}
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值