PAT乙 1085. PAT单位排行 (25)

题目地址:PAT1085.PAT单位排行(25)

易错分析:

    这里如果程序没有错,依然会有4、5两个超大测试样例通不过,这里我是通过把能换cin的地方全换成scanf,能换cout的地方全换成printf,最后不负我望,两个都通过了。

解题过程:

    首先可以建立一个结构体,这样做可以方便排序。另外我用了三个map,分别保存每个学校的学校成绩,报考人数,和学校姓名。最后通过sort排序,按要求输出就ok。

Tips:

另外我还发现了map的键如果是string类型的,用char型数组也是可以当键的。

程序:

#include <iostream>
#include <algorithm>
#include <string.h>
#include <cctype>
#include <map>
#include <cstdio>
using namespace std;

struct School
{
	char name[7];	// 学校名
	int grade;		// 学校加权总分
	int people;		// 学校人数
	int rank;		// 学校排名
}S[100001];

int cmp(School s1, School s2)
{	/* 按题目要求进行排序 */
	if (s1.grade != s2.grade)
		return s1.grade > s2.grade;
	else 
	{
		if (s1.people != s2.people)
			return s1.people < s2.people;
		else
			return strcmp(s1.name, s2.name) < 0;
	}
}

void ToLower(char *s)
{	/* 大小写转换 */
	for (int i = 0; i < strlen(s); i++)
		s[i] = tolower(s[i]);
}

int main(int argc, char const *argv[])
{	/* 能用scanf的地方就用scanf,能用printf的地方就用printf,不然会超时 */
	int N, idx = 0;
	double grade;
	char ID[7], name[7];
	scanf("%d", &N);
	map <string, double> mGrade, mNum, mName;	// 保存学校成绩,和学校人数,和学校姓名
	for (int i = 0; i < N; i++)
	{
		scanf("%s %lf %s", ID, &grade, name);
		ToLower(name);	// 全部转为小写
		if (!mName[name])
		{	/* 记录不重复的名字和个数 */
			strcpy(S[idx++].name, name);
			mName[name]++;
		}
		mNum[name]++;
		if (ID[0] == 'T')
			mGrade[name] += grade*1.5;
		else if (ID[0] == 'A')
			mGrade[name] += grade;
		else
			mGrade[name] += grade/1.5; 
	}
	for (int i = 0; i < idx; i++)
	{
		S[i].grade = (int)mGrade[S[i].name];
		S[i].people = mNum[S[i].name];
	}
	sort(S, S+idx, cmp);
	printf("%d\n", idx);	// 输出单位个数
	S[0].rank = 1;
	cout << 1 << " " << S[0].name << " " << S[0].grade << " " << S[0].people << endl;
	for (int i = 1; i < idx; i++) 
	{	
		if (S[i].grade == S[i-1].grade)	// 如果成绩相同
			S[i].rank = S[i-1].rank;
		else
			S[i].rank = i+1;
		printf("%d %s %d %d\n",S[i].rank, S[i].name, S[i].grade, S[i].people);
	}
	return 0;
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值