(字符串/map)PTA BASIC LEVEL 1085 单位排行

这题的思路与1080 类似,总的来说就是

1、建立学生和学校的结构体处理输入

2、使用map容器,将学校的名字和学校作为键和值连接起来,这样会快很多,处理测试点4和5这样的大数据测试点时就不会超时(不然肯定超时,使用键值检索时间都已经到500多ms了,要是一个一个检索时间复杂度太高)

此外键值图map没有什么不好理解的,主要思想类似于数组的下标引用法,如果学生的学号是纯数字,那么就利用数组下标存储学号,这样就可以快速访问;那么同理,如果想要通过学校的名字——即字符串这种类型来实现快速访问的话,就利用键值图,构建string——任意你想要类型的链接,这样就可以O(1)时间访问。

3、然后按照题目要求对map中的元素排序,这里我了解到的有两个方法:

1)第一是将map中的元素压入vector容器中,然后利用sort函数排序。注意vecotor元素的类型是pair类,也就是map中元素的类型。

2)第二种是利用map自己本身的排序属性,在结构体种重载你定义的结构体的<号

我选择的是第一种

解答:

#include<iostream>
#include<cstring>
#include<map>
#include<algorithm>
#include<cctype>
#include<vector>
using namespace std;
struct stu{
	string no;
	float score;
	string sch;
};
struct sch{
	float score;int stu_num;string no;
	sch(){score=0;stu_num=0;no="";	}
	sch(string n,int s,int st){no=n;score=s;stu_num=st;}
};

bool cmp(pair<string,sch> s1,pair<string,sch> s2)
{
	if(s1.second.score!=s2.second.score)
		return s1.second.score>s2.second.score;
	else if(s1.second.stu_num!=s2.second.stu_num)
		return s1.second.stu_num<s2.second.stu_num;
	else return s1.second. no<s2.second.no; 
}
int main() 
{
	map<string,sch> m;
	int n;
	cin>>n;
	stu s[n];
	for(int i=0;i<n;i++)
	{	cin>>s[i].no>>s[i].score>>s[i].sch;
		transform(s[i].sch.begin(),s[i].sch.end(),s[i].sch.begin(),::tolower);
		
		if(m[s[i].sch].stu_num==0)
		{	
			switch(s[i].no[0])
			{
				case 'B': m[s[i].sch].no=s[i].sch;
						  m[s[i].sch].score=s[i].score/1.5;
						  m[s[i].sch].stu_num=1;
							break;
				case 'A': m[s[i].sch].no=s[i].sch;
						  m[s[i].sch].score=s[i].score;
						  m[s[i].sch].stu_num=1;
							break;
				case 'T':m[s[i].sch].no=s[i].sch;
						  m[s[i].sch].score=s[i].score*1.5;
						  m[s[i].sch].stu_num=1;
			}

		}
		else {
			switch(s[i].no[0])
			{
				case 'A':m[s[i].sch].score+=s[i].score;
				break;
				case 'B':m[s[i].sch].score+=s[i].score/1.5;
				break;
				case 'T':m[s[i].sch].score+=s[i].score*1.5;
			}
			m[s[i].sch].stu_num++;
		}
}
	for(auto i=m.begin();i!=m.end();i++)
	(*i).second.score=(int)(*i).second.score;
	vector<pair<string,sch>> st;
	for(auto i=m.begin();i!=m.end();i++)
	{
		st.push_back(*i);
		//cout<<(*i).second.no<<" "<<(*i).second.score<<endl;
	}
	sort(st.begin(),st.end(),cmp);
	int order=1;int count=1;
	cout<<st.size()<<endl; 
	for(int i=0;i<st.size()-1;i++)
	{
		
	cout<<order<<" "<<st[i].second.no<<" "<<st[i].second.score<<" "<<st[i].second.stu_num<<endl;
	if(st[i].second.score==st[i+1].second.score)
	{
		count++;
	}
	else{
		order+=count;
		count=1;
	}
}
	int i=st.size()-1;
	cout<<order<<" "<<st[i].second.no<<" "<<st[i].second.score<<" "<<st[i].second.stu_num<<endl;
	
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值