【PAT】B1085 PAT单位排行(25 分)(c++实现)

终于做的有点眉目了,今天学习了一点stl的皮毛,解题瞬间变容易了
下边开始分析本题
这道题如果用纯c解决实在太麻烦,试了半天两个超时,果断放弃,还是用map方便;
我的方法与柳神的方法是有区别的,我只是用map来保存学校在结构体数组中的地址。
代码中每一块都有注释,绝对不是耍流氓的直接贴一片代码,

注意:
最后学校的成绩要求取整,为了省去遍历一遍学校结构体数组,所有用到了float性分数的地方都强转了int


#include<iostream>
#include<algorithm>
#include<map>
using namespace std;
struct sch{
	string name;
	float score=0;
	int stu=0;
}arr[100005];//这个数组可以小点,学校怎么可能这么多
bool cmp(sch A,sch B){
	if((int)A.score!=(int)B.score) return (int)A.score>(int)B.score;//分数不同,谁大谁在前
	else if(A.stu!=B.stu) return A.stu<B.stu;		//分数相同,学生数不同,学生数小的在前
	else return A.name<B.name;			//否则只能用字典序了,谁小谁的字典序在前
}
int main(){
	int N;scanf("%d",&N);			//学生数的定义和输入
	int num=0;//学校数
	map<string,int> mp;							//mp用来存放学校名字符串到结构体数组的映射
	for(int i=0;i<N;i++){
		string id,school;float score;
		cin>>id;scanf("%f",&score);cin>>school;
		for(int j=0;j<school.length();j++){			//名字变小写
			school[j]=tolower(school[j]);
		}
		if(id[0]=='B') score/=1.5;			//计算当前学生可以给学校带来多少分
		if(id[0]=='T') score*=1.5;
		if(mp.count(school)==0){			//如果此学校第一次出现
			mp[school]=num++;
			arr[num-1].name=school;
		}
		arr[mp[school]].score+=score;			//给这个学校加上这个学生的分
		arr[mp[school]].stu++;			//学校的学生数加加
	}
	sort(arr,arr+num,cmp);				//对结构体数组进行排序
	int mingci=1;
	printf("%d\n1 ",num);				//先输出了学校数和第一名的学校
	cout<<arr[0].name;
	printf(" %d %d",(int)arr[0].score,arr[0].stu);
	for(int i=1;i<num;i++){						//从第二个学校开始的
		if((int)arr[i].score!=(int)arr[i-1].score)	//如果分数和前一个学校相同,当然mingci就行同了
			mingci=i+1;				//如果分数不同,那么名次正好等于i+1
		printf("\n%d ",mingci);				//输出当前学校的信息
		cout<<arr[i].name;
		printf(" %d %d",(int)arr[i].score,arr[i].stu);
	}
	return 0;
}

posted @ 2018-08-16 18:34  路明天  阅读(727)  评论(0编辑  收藏  举报