PAT(甲级)2018年冬季考试 7-2 Decode Registration Card of PAT

Posted CSU迦叶

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PAT(甲级)2018年冬季考试 7-2 Decode Registration Card of PAT相关的知识,希望对你有一定的参考价值。

目录

体会

代码(非满分)

改进

AC代码

体会

这题主要是考察对STL中string,map,vector的应用以及自定义sort()应用。

类型1和2的处理很容易。

类型3要求对于指定date,按照每个考场进行分类,记录不同考场的人数,按照人数非升序,考场号升序(如果前者相同)输出。

我一开始还是很死板地想全在sort里面把它给解决掉,但是一直没做出来。并且收获了map的键和值都不可以是数组的结论。

后面改用这个数据结构

map<int,int> doubleMap[maxn];//map<site,num> doubleMap[date]

map是可以判空、计数和遍历的。而且初始化int值为0,这方便记每个考场的人数。

虽然map不可以排序,但是可以声明和map同样类型的向量vector<int,int>来排序,通过遍历把map的键值拷贝到vector中。遍历的过程中it->first和it->second可以调换位置,虽然本题不这么做也可。

比较函数cmp的参数类型设置为pair<int,int>即可。

以下是类型三相关代码

#part1 
bool cmp3(pair<int,int> a,pair<int,int> b){
	return a.first!=b.first?a.first>b.first:a.second<b.second; 
}

#part2
//type 3
sscanf(str.substr(4,6).c_str(),"%d",&date);	
doubleMap[date][site] ++;

#part3
int date;
cin>>date;
printf("Case %d: 3 %d\\n",i,date);
if(doubleMap[date].size()==0)printf("NA\\n");
else{
	vector<pair<int,int> > vi;
	map<int,int>::iterator it = doubleMap[date].begin();
	for(;it!=doubleMap[date].end();it++){
		vi.push_back(make_pair(it->second,it->first));
	}
	sort(vi.begin(),vi.end(),cmp3);
	for(int j=0;j<vi.size();j++){
		printf("%d %d\\n",vi[j].second,vi[j].first);
	}
}

代码(非满分)

#include<cstdio>
#include<cmath>
#include<algorithm>
#include<iostream>
#include<vector>
#include<string>
#include<queue>
#include<map>
#include<cstring>
#include<set>

using namespace std;

const int maxn = 1000001;

map<string,int> cardToGrade;

map<char,vector<string> > levelToCard;

map<int,vector<string> > siteToCard;

map<int,int> doubleMap[maxn];//map<site,num> doubleMap[date]

bool cmp1(string a,string b){
	return cardToGrade[a]!=cardToGrade[b]?cardToGrade[a]>cardToGrade[b]:a<b;
}

bool cmp3(pair<int,int> a,pair<int,int> b){
	return a.first!=b.first?a.first>b.first:a.second<b.second; 
}

int main(){
	
	int pNum,qNum;
	scanf("%d %d",&pNum,&qNum);
	
	string str;
	int grade,site,date;
	for(int i=0;i<pNum;i++){	
		cin>>str;
		scanf("%d",&grade);
		cardToGrade[str] = grade;
		//tyep 1 
		char level = str[0];
		levelToCard[level].push_back(str);
		//type 2
		sscanf(str.substr(1,3).c_str(),"%d",&site);
		siteToCard[site].push_back(str);
		//type 3
		sscanf(str.substr(4,6).c_str(),"%d",&date);	
		doubleMap[date][site] ++;
	}
	
	for(int i=1;i<=qNum;i++){
		int t;
		cin>>t;
		switch(t){
			case 1:
				char level;
				cin>>level;
				printf("Case %d: 1 %c\\n",i,level);
				if(levelToCard[level].size()==0)printf("NA\\n");
				else{
					sort(levelToCard[level].begin(),levelToCard[level].end(),cmp1);
					for(int j=0;j<levelToCard[level].size();j++){
						cout<<levelToCard[level][j]<<" "<<cardToGrade[levelToCard[level][j]]<<endl;
					}
				} 
				break;
			case 2:
				int site;
				cin>>site;
				printf("Case %d: 2 %d\\n",i,site);
				if(siteToCard[site].size()==0)printf("NA\\n");
				else{
					int nt = siteToCard[site].size();
					int ns = 0;
					for(int j=0;j<nt;j++){
						ns += cardToGrade[siteToCard[site][j]];
					}
					cout<<nt<<" "<<ns<<endl;
				}
				break;
			case 3:
				int date;
				cin>>date;
				printf("Case %d: 3 %d\\n",i,date);
				if(doubleMap[date].size()==0)printf("NA\\n");
				else{
					vector<pair<int,int> > vi;
					map<int,int>::iterator it = doubleMap[date].begin();
					for(;it!=doubleMap[date].end();it++){
						vi.push_back(make_pair(it->second,it->first));
					}
					sort(vi.begin(),vi.end(),cmp3);
					for(int j=0;j<vi.size();j++){
						printf("%d %d\\n",vi[j].second,vi[j].first);
					}
				}
				
				break;	
		}
	}
	
	

	return 0;
}

改进

上述代码提交后还有一个测试用例是错的,一个是超时的

超时解决方案:

用unordered_map取代map(前者在查找时更快)

注意dev本地上可能要加上

#include<tr1/unordered_map>
using namespace std::tr1;

提交时只需要加

#include<unordered_map>

 另一改进是,我不再一开始就对输入进行映射分类,而是先存进vector中,再根据需要取所需。

之前可怕的map数组也就变成了普通的map变量

unordered_map<string,int> umap;

另一个小小改进是,把site和date都不看成int而直接视作string,反而遍历了后序的比较。写sscanf不麻烦吗? 

AC代码

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<bits/stdc++.h>
#include<stdlib.h>
#include<time.h>
#include<vector>
#include<set>
#include<string>
#include<tr1/unordered_map>

using namespace std;
using namespace std::tr1;
typedef long long LL;

const int maxn = 10007;
const int MOD = 1000000007;
const int INF = 1000000000;//INF:下确界  
const LL SUP = (1LL<<63)-1;//SUP:上确界 
const double eps = 1e-5;

struct Node{
	string id;
	int v;
};

bool cmp1(const Node &a,const Node &b){
	return a.v!=b.v?a.v>b.v:a.id<b.id;
}

bool cmp3(pair<string,int> a,pair<string,int> b){
	return a.second!=b.second?a.second>b.second:a.first<b.first;
}

Node node[maxn];

int main(){
	
	
	int pNum,qNum;
	cin>>pNum>>qNum;
	
	for(int i=0;i<pNum;i++){
		string id;
		int v;
		cin>>id>>v;
		node[i].id = id;
		node[i].v = v;
	}
	
	for(int i=1;i<=qNum;i++){
		int t,num = 0,score = 0;
		vector<Node> vi;
		string site,date;
		unordered_map<string,int> umap;
		vector<pair<string,int> > vi3;
		cin>>t;
		switch(t){
			case 1:
				char ch;
				cin>>ch;
				printf("Case %d: 1 %c\\n",i,ch);
				for(int j=0;j<pNum;j++){
					if(node[j].id[0]==ch)vi.push_back(node[j]);
				}
				if(vi.size()==0)printf("NA\\n");
				else{
					sort(vi.begin(),vi.end(),cmp1);
					for(int j=0;j<vi.size();j++){
						printf("%s %d\\n",vi[j].id.c_str(),vi[j].v);
					}
				}
				break;
			case 2:
				cin>>site;
				printf("Case %d: 2 %s\\n",i,site.c_str());
				for(int j=0;j<pNum;j++){
					if(node[j].id.substr(1,3)==site){
						num ++;
						score += node[j].v; 
					}
				}
				if(num == 0)printf("NA\\n");
				else printf("%d %d\\n",num,score);
				break;
			case 3:
				cin>>date;
				printf("Case %d: 3 %s\\n",i,date.c_str());
				for(int j=0;j<pNum;j++){
					if(node[j].id.substr(4,6)==date)umap[node[j].id.substr(1,3)] ++;
				}
				if(umap.size()==0)printf("NA\\n");
				else{
					unordered_map<string,int>::iterator it = umap.begin();
					for(;it!=umap.end();it++){
						vi3.push_back(make_pair(it->first,it->second));
					}
					sort(vi3.begin(),vi3.end(),cmp3);
					for(int j=0;j<vi3.size();j++){
						printf("%s %d\\n",vi3[j].first.c_str(),vi3[j].second);
					}
				}					
		}
	}
	

		
	return 0;
}

以上是关于PAT(甲级)2018年冬季考试 7-2 Decode Registration Card of PAT的主要内容,如果未能解决你的问题,请参考以下文章

PAT(甲级)2019年冬季考试 7-2 Block Reversing

PAT(甲级)2018年冬季考试 7-1 Google Recruitment

PAT(甲级)2018年冬季考试 7-3 Vertex Coloring

PAT(甲级)2018年冬季考试 7-4 Heap Paths(非递归与递归解法)

PAT2021年冬季考试甲级,摸鱼游记92分

PAT2021年冬季考试甲级,摸鱼游记92分