1095 解码PAT准考证分数 25(c++,stl的map、sort应用)

PAT 准考证号由 4 部分组成:
第 1 位是级别,即 T 代表顶级;A 代表甲级;B 代表乙级;
第 2~4 位是考场编号,范围从 101 到 999;
第 5~10 位是考试日期,格式为年、月、日顺次各占 2 位;
最后 11~13 位是考生编号,范围从 000 到 999。
现给定一系列考生的准考证号和他们的成绩,请你按照要求输出各种统计信息。

输入格式:

输入首先在一行中给出两个正整数 N(≤10​4​​ )和 M(≤100),分别为考生人数和统计要求的个数。

接下来 N 行,每行给出一个考生的准考证号和其分数(在区间 [0,100] 内的整数),其间以空格分隔。

考生信息之后,再给出 M 行,每行给出一个统计要求,格式为:类型 指令,其中

类型 为 1 表示要求按分数非升序输出某个指定级别的考生的成绩,对应的 指令 则给出代表指定级别的字母;
类型 为 2 表示要求将某指定考场的考生人数和总分统计输出,对应的 指令 则给出指定考场的编号;
类型 为 3 表示要求将某指定日期的考生人数分考场统计输出,对应的 指令 则给出指定日期,格式与准考证上日期相同。
输出格式:

对每项统计要求,首先在一行中输出 Case #: 要求,其中 # 是该项要求的编号,从 1 开始;要求 即复制输入给出的要求。随后输出相应的统计结果:

类型 为 1 的指令,输出格式与输入的考生信息格式相同,即 准考证号 成绩。对于分数并列的考生,按其准考证号的字典序递增输出(题目保证无重复准考证号);
类型 为 2 的指令,按 人数 总分 的格式输出;
类型 为 3 的指令,输出按人数非递增顺序,格式为 考场编号 总人数。若人数并列则按考场编号递增顺序输出。
如果查询结果为空,则输出 NA。

输入样例:

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


输出样例:

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

亮点:

  1. 对自定义vector的使用与自定义vector的排序;
  2. 对map关联容器的排序与map关联容器的访问;
  3. 用sort进行排序等;
  4. 将c++的string类 转化成字符数组的形式用printf输出;

因为之前再用c++的stl库,所以遇到这种题都往stl方面想:

大致思路都是将数据存到结构体里,每次遇到 1,2,3种情况,在相应的结构体里找到需要用的信息,然后存放的vector或者map中、然后用sort进行排序;主要难点就是如何对自定义vecotr容器进行排序,还有map键值对进行排序;

因为sort只能对容器进行排序,比如vector、list等,所以在对map排序的情况下可以将map放入vector中,然后自定义vector的排序规则,然后对vector进行排序:

这里要对map关联容器排序的话,如果对key值进行排序,只需要自定义规则,写入定义的map即可,例如: map<string,int,cmp>m;  m容器会按照cmp规则排序;

如果要对value进行排序,就必须要重载operator方法,写进类里面,然后进行排序;

 刚开始做的时候有两个运行超时,源码如下:

#include<bits/stdc++.h>
using namespace std;

struct infor
{
	string id;
	int grade;
}stu[10000];

bool cmp1(infor p1,infor p2)
{
	if(p1.grade!=p2.grade)
		return p1.grade > p2.grade;
	else
		return p1.id<p2.id;
}

struct cmp2
{
	bool operator()(pair<string,int> &p1,pair<string,int> &p2)
	{
		if(p1.second==p2.second)
			return p1.first<p2.first;
		else
			return p1.second>p2.second;
	}
}; 
int main()
{
	int M,N;
	cin>>M>>N;  //8 4
	for(int i=0;i<M;i++)
	{
		cin>>stu[i].id>>stu[i].grade;
	}
	for(int i=0;i<N;i++)
	{
		int x;
		cin>>x;
		if(x==1)
		{
			char op;
			vector<infor>v;
			vector<infor>::iterator it;
			int flag=0;
			cin>>op;
			for(int j=0;j<M;j++)
			{
				if(stu[j].id[0]==op)
				{
					flag=1;
					v.push_back(stu[j]);
				}
			}
			sort(v.begin(),v.end(),cmp1);
			printf("Case %d: 1 %c\n",i+1,op);
			if(flag==1)
			{
					for(it=v.begin();it!=v.end();it++)
						cout<<it->id<<" "<<it->grade<<endl;
					v.clear();
			}
			else
				
				printf("NA\n");
		}
		if(x==2)
		{
			int sum=0,count=0,flag=0;
			string kao;
			cin>>kao;
			printf("Case %d: 2 ",i+1);
			cout<<kao<<endl;
			for(int j=0;j<M;j++)
			{
				string nn=(stu[j].id).substr(1,3);
				if(nn==kao)
				{
					flag=1;
					count++;
					sum=sum+stu[j].grade;
				}
			}
			if(flag==1)
				cout<<count<<" "<<sum<<endl;
			else
				printf("NA\n");
		}
		if(x==3)
		{
			string kao;
			int flag=0;
			map<string,int>m;
			cin>>kao;
			printf("Case %d: 3 ",i+1);
			cout<<kao<<endl; 
			for(int j=0;j<M;j++)
			{
				if(kao==(stu[j].id).substr(4,6))
				{
					flag=1;
					m[(stu[j].id).substr(1,3)]++;
				}
			}
			if(flag==1)
			{
				vector<pair<string,int> >v1(m.begin(),m.end());
				vector<pair<string,int> >::iterator it1;
				sort(v1.begin(),v1.end(),cmp2());
				for(it1=v1.begin();it1!=v1.end();++it1)
				{
					cout<<it1->first<<" "<<it1->second<<endl;
				}
				v1.clear();
			}
			else
				printf("NA\n");
		}
	}
	return 0;
}

 这段代码提交后有两个运行超时,然后很神奇的是,如果将里面的cout 换成 printf.....最最最最最神奇的来了,代码全部AC,后面查了一下,printf的运行速度要是cout的三倍左右,这个就很想不通,c++特有的cout,cin,还能出现运行超时,这个测试点也很恶心;谁能想到运行超时尽然不是优化代码的问题;

 后面附AC代码:

(用printf 替换的 cout 对比我用注释出来了);

#include<bits/stdc++.h>
using namespace std;

struct infor
{
	string id;
	int grade;
}stu[10000];

bool cmp1(infor p1,infor p2)
{
	if(p1.grade!=p2.grade)
		return p1.grade > p2.grade;
	else
		return p1.id<p2.id;
}

struct cmp2
{
	bool operator()(pair<string,int> &p1,pair<string,int> &p2)
	{
		if(p1.second==p2.second)
			return p1.first<p2.first;
		else
			return p1.second>p2.second;
	}
}; 
int main()
{
	int M,N;
	cin>>M>>N;  //8 4
	for(int i=0;i<M;i++)
	{
		cin>>stu[i].id>>stu[i].grade;
	}
	for(int i=0;i<N;i++)
	{
		int x;
		cin>>x;
		if(x==1)
		{
			char op;
			vector<infor>v;
			vector<infor>::iterator it;
			int flag=0;
			cin>>op;
			for(int j=0;j<M;j++)
			{
				if(stu[j].id[0]==op)
				{
					flag=1;
					v.push_back(stu[j]);
				}
			}
			sort(v.begin(),v.end(),cmp1);
			printf("Case %d: 1 %c\n",i+1,op);
			if(flag==1)
			{
					for(it=v.begin();it!=v.end();it++)
					{
						printf("%s %d\n",(it->id).c_str(),it->grade);
					}
//						cout<<it->id<<" "<<it->grade<<endl;
					v.clear();
			}
			else
				printf("NA\n");
		}
		if(x==2)
		{
			int sum=0,count=0,flag=0;
			string kao;
			cin>>kao;
			printf("Case %d: 2 ",i+1);
			cout<<kao<<endl;
			for(int j=0;j<M;j++)
			{
				string nn=(stu[j].id).substr(1,3);
				if(nn==kao)
				{
					flag=1;
					count++;
					sum=sum+stu[j].grade;
				}
			}
			if(flag==1)
				printf("%d %d\n",count,sum);
//				cout<<count<<" "<<sum<<endl;
			else
				printf("NA\n");
		}
		if(x==3)
		{
			string kao;
			int flag=0;
			map<string,int>m;
			cin>>kao;
			printf("Case %d: 3 ",i+1);
			cout<<kao<<endl; 
			for(int j=0;j<M;j++)
			{
				if(kao==(stu[j].id).substr(4,6))
				{
					flag=1;
					m[(stu[j].id).substr(1,3)]++;
				}
			}
			if(flag==1)
			{
				vector<pair<string,int> >v1(m.begin(),m.end());
				vector<pair<string,int> >::iterator it1;
				sort(v1.begin(),v1.end(),cmp2());
				for(it1=v1.begin();it1!=v1.end();++it1)
				{
					printf("%s %d\n",(it1->first).c_str(), it1->second);
//					cout<<it1->first<<" "<<it1->second<<endl;
				}
				v1.clear();
			}
			else
				printf("NA\n");
		}
	}
	return 0;
}

总的来说,这篇文章对stl的应用帮助很大,有自定义的vector与自定义vector的排序,还有map的排序(存放到vector);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值