PAT1095 解码PAT准考证

遇到的问题
1.只对类型2做了异常处理(未查询到结果输出NA) 对应测试点1
2.对类型1的查询没有做分数相等时按准考证号的字典序排序 对应测试点2,3
3.cout超时,改用printf通过, 对应测试点4
4.类型1和类型2都很好处理,关键在于类型3中,如何对每个考场的人数进行统计后排序还能输出对应的考场号,考虑到这种关系应该是一个哈希表,但是用数组实现的哈希表在排序后无法实现对人数值给出对应的考场号,因此考虑使用map/unordered_map,可以实现在输出人数的同时还能给出对应的考场号,但是这两种数据结构都无法进行sort排序,查阅相关资料得知可以封装成vector去排序。

对unordered_map进行人数统计的核心代码

int cnt=0;//符合结果计数 
	vector<pair<string,int>> rif;
	unordered_map<string,int> Room;//相同日期的考场号、人数 
	//vector<pair<string, int> >::iterator it;
	for(int i=0;i<n;i++){
		if(stu[i].Id.substr(4,6)==date){//日期筛选 
			string temp=stu[i].Id.substr(1,3);//截取考场号 
			Room[temp]++;//考场号人数+1 
			cnt++;
		}
	}

对unordered_map进行封装vector并排序的核心代码

for(auto it=Room.begin();it!=Room.end();it++)
			rif.push_back(make_pair(it->first,it->second));//将unrodered_map(哈希表)封装入vector
		sort(rif.begin(),rif.end(),cmp2);//排序
		for(auto it=rif.begin();it!=rif.end();it++)
			printf("%s %d\n", it->first.c_str(), it->second);

实际上运用的还是结构体排序的思想,但是由于结构体在统计各个考场号对应的人数时操作不方便,无法像哈希表一样直接让对应项的数值++,所以采用哈希表的数据结构

完整ac代码:

#include <bits/stdc++.h>
using namespace std;
struct StuInfo{
    string Id;
    int Score;
};
struct RoomInfo{
	string RoomId;
	int humancnt;
};
bool cmp1(StuInfo a,StuInfo b);
bool cmp2(const pair<string,int> &p1,const pair<string,int> &p2);
void ProcessOne(StuInfo stu[],int n,string Clas);
void ProcessTwo(StuInfo stu[],int n,string Clas);
void ProcessThree(StuInfo stu[],int n,string date);
int main(){
    int N,M;
    cin>>N>>M;
    struct StuInfo Stu[N];
    for(int i=0;i<N;i++)
    {
        cin>>Stu[i].Id>>Stu[i].Score;
    }
    int type;
    string code;
    for(int j=1;j<=M;j++){
    	
        cin>>type>>code;
        //类型1的指令 
        if(type==1){
            cout<<"Case "<<j<<": "<<type<<" "<<code<<endl;
            ProcessOne(Stu,N,code);
        }
        else if(type==2){
        	cout<<"Case "<<j<<": "<<type<<" "<<code<<endl;
        	ProcessTwo(Stu,N,code);
		}
		else if(type==3){
			cout<<"Case "<<j<<": "<<type<<" "<<code<<endl;
			ProcessThree(Stu,N,code);
		}
    }
}
void ProcessOne(StuInfo stu[],int n,string Clas){
    StuInfo stuX[10000];
    int cnt=0;
    //收集所有级别为目标级别的考生
    for(int i=0;i<n;i++){
        if(stu[i].Id[0]==Clas[0])
        {
            stuX[cnt++]=stu[i];
        }
    }
    //对目标群体进行排序
    sort(stuX,stuX+cnt,cmp1);
    if(cnt==0)
	printf("NA\n");
    for(int i=0;i<cnt;i++){
        //cout<<stuX[i].Id<<" "<<stuX[i].Score<<endl;
        printf("%s %d\n", stuX[i].Id.c_str(),stuX[i].Score);
    }
    
}
bool cmp1(StuInfo a,StuInfo b){
    if(a.Score!=b.Score)
    return a.Score>b.Score;
    else 
    return a.Id<b.Id;
}
void ProcessTwo(StuInfo stu[],int n,string Clas){
	int ScoreSum=0;
	int HeadCnt=0;
	for(int i=0;i<n;i++){
		if(stu[i].Id.substr(1,3)==Clas){
			HeadCnt++;
			ScoreSum+=stu[i].Score;
		}
	}
	if(HeadCnt==0)
	{
		printf("NA\n");
	//cout<<Clas<<" "<<stu[2].Id.substr(1,3);
	}
	else
	//cout<<HeadCnt<<" "<<ScoreSum<<endl;
	printf("%d %d\n",HeadCnt,ScoreSum) ;
}
void ProcessThree(StuInfo stu[],int n,string date){
	int cnt=0;//符合结果计数 
	vector<pair<string,int>> rif;
	unordered_map<string,int> Room;//相同日期的考场号、人数 
	//vector<pair<string, int> >::iterator it;
	//int j=0;
	for(int i=0;i<n;i++){
		if(stu[i].Id.substr(4,6)==date){//日期筛选 
			string temp=stu[i].Id.substr(1,3);//截取考场号 
			Room[temp]++;//考场号人数+1 
			cnt++;
		}
	}
	if(cnt>0){
		for(auto it=Room.begin();it!=Room.end();it++)
			rif.push_back(make_pair(it->first,it->second));
		sort(rif.begin(),rif.end(),cmp2);
		for(auto it=rif.begin();it!=rif.end();it++)
			printf("%s %d\n", it->first.c_str(), it->second);
	}
	else
		printf("NA\n");
}

bool cmp2(const pair<string,int> &p1,const pair<string,int> &p2)
{
	return p1.second != p2.second ? p1.second > p2.second:p1.first < p2.first;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值