1085 PAT单位排行 (25 分)

本题要求实现PAT考试后的单位排行榜功能,根据考生的得分和单位进行排序,展示单位的加权总分和考生人数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

每次 PAT 考试结束后,考试中心都会发布一个考生单位排行榜。本题就请你实现这个功能。

输入格式:

输入第一行给出一个正整数 N(≤10​5​​),即考生人数。随后 N 行,每行按下列格式给出一个考生的信息:

准考证号 得分 学校

其中准考证号是由 6 个字符组成的字符串,其首字母表示考试的级别:B代表乙级,A代表甲级,T代表顶级;得分是 [0, 100] 区间内的整数;学校是由不超过 6 个英文字母组成的单位码(大小写无关)。注意:题目保证每个考生的准考证号是不同的。

输出格式:

首先在一行中输出单位个数。随后按以下格式非降序输出单位的排行榜:

排名 学校 加权总分 考生人数

其中排名是该单位的排名(从 1 开始);学校是全部按小写字母输出的单位码;加权总分定义为乙级总分/1.5 + 甲级总分 + 顶级总分*1.5整数部分考生人数是该属于单位的考生的总人数。

学校首先按加权总分排行。如有并列,则应对应相同的排名,并按考生人数升序输出。如果仍然并列,则按单位码的字典序输出。

输入样例:

10
A57908 85 Au
B57908 54 LanX
A37487 60 au
T28374 67 CMU
T32486 24 hypu
A66734 92 cmu
B76378 71 AU
A47780 45 lanx
A72809 100 pku
A03274 45 hypu

输出样例:

5
1 cmu 192 2
1 au 192 3
3 pku 100 1
4 hypu 81 2
4 lanx 81 2
#include<bits/stdc++.h>
using namespace std;
string lower(string s){
	string temp = "";
	for(int i=0;i<s.length();i++)temp+=tolower(s[i]);
	return temp;
}
struct node{
	int num=0;
	string name;
	double sum=0.0;
};
bool cmp(node a, node b){
	if((int)a.sum==(int)b.sum){
		if(a.num==b.num){
			return a.name<b.name;
		}else
			return a.num<b.num;
	}else{
		return (int)a.sum>(int)b.sum;
	}
}
int main() {
	int n,mark;
	string id,school;
	unordered_map<string,node>m;
	unordered_set<string>set;
	cin>>n;
	for(int i=0;i<n;i++){
		cin>>id>>mark>>school;
		school = lower(school);
		m[school].name = school;
		if(id[0]=='A')m[school].sum+=mark;
		else if(id[0]=='B')m[school].sum+=(double)mark/1.5;
		else m[school].sum+=(double)mark*1.5;
		m[school].num++;
		set.insert(school);
	}
	cout<<set.size()<<endl;
	vector<node>v;
	for(auto i=set.begin();i!=set.end();i++){
		v.push_back(m[*i]);
	}
	sort(v.begin(),v.end(),cmp);
	int cou = 1;
	int temp = cou;
	mark = (int)v[0].sum;
	for(int i=0;i<v.size();i++){
		
		if((int)v[i].sum!=mark){
			temp = cou;
			mark = (int)v[i].sum;
		}
		cout<<temp<<" "<<v[i].name<<" "<<(int)v[i].sum<<" "<<v[i].num<<endl;
		cou++;
	}
	return 0;
}

 

<think>好的,我需要解决用户关于PAT 1085题目中测试点5的问题。首先,我需要回顾题目要求和常见的测试点问题。 根据引用[2],PAT常考的排名方式是同布排名,即相同数的单位应并列,后续排名跳过。例如,如果有两个单位并列第一,下一个单位应该是第三名,而不是第二。这可能与测试点5相关,因为如果排名处理不当,会导致错误。 测试点5可能涉及浮点数计算或精度问题。例如,使用浮点数计算总时,可能存在精度丢失,导致比较出错。引用[3]提到总的计算涉及指数运算,需要注意十进制的处理,避免累积误差。可能需要在计算时使用整数运算代替浮点数,例如将所有成绩转换为整数后再比较。 另外,单位名称的大小写是否敏感也是常见问题。题目可能要求不考虑大小写,但存储时需要统一格式,否则比较时会出错。例如,将所有单位名称转换为小写后再处理。 数据结构的选择也可能影响结果。例如,使用哈希表存储单位信息时,需要确保键的唯一性。合并不同考生成绩时,需正确累加各部数,并处理可能的小数位数不一致问题。 还有可能是输出格式的问题,例如排名、单位名称、总和考生数的对齐方式不符合要求,导致测试点失败。需要严格按照题目要求的格式输出,包括空格、顺序等。 最后,测试点5可能包含大规模数据,需要注意算法的时间复杂度。使用高效的排序算法(如快速排序)和合适的数据结构可以避免超时问题。引用[1]提到备考时需注意代码效率,这可能与此相关。</think>### PAT 1085 单位排行 测试点5 解法与注意事项 #### 1. **排名规则的正确实现** - **同同名次**:测试点5可能考察单位相同但排名未正确处理的情况。例如,三个单位依次为 90、90、85,前两个应并列第1名,第三个应为第3名(而非第2名)。实现时需要先按总降序排序,再遍历处理排名: ```python sorted_list = sorted(units.items(), key=lambda x: (-x[1]['total'], x[0])) rank = 1 for i in range(len(sorted_list)): if i > 0 and sorted_list[i][1]['total'] != sorted_list[i-1][1]['total']: rank = i + 1 sorted_list[i][1]['rank'] = rank ``` 参考类似排名逻辑见[^2]。 #### 2. **总计算的精度问题** - **浮点数陷阱**:题目中总计算公式可能涉及浮点运算(如$10^{-k}$),直接使用浮点类型可能导致精度丢失。例如,测试点5可能包含极端数据,如多次累加后误差累积。建议将数转换为整数处理,例如: ```python # 将小数部转为整数(假设最多有3位小数) total = integer_part * 1000 + decimal_part ``` 类似数值处理思路可参考[^3]。 #### 3. **单位名称的大小写统一** - **大小写不敏感**:题目可能要求单位名称不区大小写(如"Pku"和"PKU"视为同一单位)。需在处理时统一转换为小写或大写: ```python school_name = input_name.strip().lower() ``` #### 4. **数据规模与性能优化** - **时间复杂度**:测试点5可能包含大量数据(如10^5条记录),需使用$O(n \log n)$的排序算法(如快速排序)。Python中建议用内置的`sorted()`函数,避免手写低效排序逻辑。 #### 5. **输出格式的严格匹配** - **字段对齐**:输出要求“排名 单位名称 总 考生人数”时,需注意: - 单位名称按原输入输出(保留大小写) - 总取整数部(如计算为95.6则输出95) - 考生人数为整数 #### 示例代码片段 ```python units = {} for record in records: school = record['school'].lower() score = int(record['score'] * 1000) # 转为整数避免浮点误差 if school not in units: units[school] = {'total': 0, 'count': 0, 'name': record['school']} units[school]['total'] += score units[school]['count'] += 1 # 转换为实际总(例如原公式为 total = A + B/1000) for school in units: units[school]['total'] = units[school]['total'] // 1000 # 取整数部 sorted_list = sorted(units.values(), key=lambda x: (-x['total'], x['name'])) # 处理排名 current_rank = 1 for i, unit in enumerate(sorted_list): if i > 0 and unit['total'] != sorted_list[i-1]['total']: current_rank = i + 1 unit['rank'] = current_rank # 输出(示例) for unit in sorted_list: print(f"{unit['rank']} {unit['name']} {unit['total']} {unit['count']}") ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值