1 条题解
-
1
题目分析
题意简述
本题涉及对教师信息的处理和排名。输入包括教师数量 和学生投票数量 。对于每个教师,有编号 、姓名 、专业 ,以及他们获得的投票信息。学生的投票信息是一个字符串,代表他们对教师的排名。程序需要根据投票信息计算每个教师的得分和投票数,并按照特定规则进行排名,最后输出排名前 名教师的详细信息。
输入
- 多组测试用例。每组测试用例首先输入教师数量 和学生投票数量 。
- 接着输入每个教师的编号 、姓名 和专业 。
- 然后输入每个学生的投票信息,是一个字符串,其中每两个字符表示一个教师的编号,代表该教师在学生心中的排名。
输出
对于每组测试用例,输出排名前 名教师的详细信息,包括排名、编号、姓名、专业、得分、投票数以及在每个排名位置上的得票数。
解题思路
初始化
- 定义教师结构体
teacher
,包含编号id
、姓名name
、专业major
、总票数votes
、总得分score
以及每个排名位置的得票数vote[10]
。 - 定义数组
ids
用于快速查找教师编号对应的结构体索引,初始化为 。 - 初始化教师信息,包括将每个教师的总票数、总得分和每个排名位置的得票数清零,并读取教师的编号、姓名和专业,同时将教师编号与结构体索引对应存储在
ids
数组中。
投票解析
- 定义函数
isFei
用于检查投票字符串是否合法。遍历投票字符串,检查每个教师编号是否存在且未被重复投票。 - 定义函数
parse
用于解析投票字符串。如果投票字符串合法,则遍历字符串,根据教师编号找到对应的教师结构体,更新其总票数、每个排名位置的得票数以及总得分。
排名与输出
- 定义比较函数
compare
,用于对教师结构体进行排序。排序规则为:总得分高的教师排在前面;如果总得分相同,则总票数多的教师排在前面;如果总得分和总票数都相同,则编号小的教师排在前面。 - 读取学生的投票信息,并调用
parse
函数进行解析。 - 对所有教师进行排序。
- 输出排名前 名教师的详细信息,包括排名、编号、姓名、专业、得分、投票数以及在每个排名位置上的得票数。输出时注意格式对齐。
代码实现
#include <iostream> #include <vector> #include <algorithm> #include <string> #include <iomanip> #include <map> using namespace std; const int scores[10] = {15, 12, 9, 7, 6, 5, 4, 3, 2, 1}; struct Teacher { string id; string name; string major; int votes; int score; vector<int> vote_counts; // 在构造函数中初始化非静态成员变量 Teacher() : votes(0), score(0), vote_counts(10, 0) {} }; bool compareTeachers(const Teacher &a, const Teacher &b) { if (a.score != b.score) return a.score > b.score; if (a.votes != b.votes) return a.votes > b.votes; return a.id < b.id; } int main() { // 这里不能使用C++11 及以上特性的优化,去掉相关代码 // ios::sync_with_stdio(false); // cin.tie(nullptr); int numT, numS; while (cin >> numT && numT != -1) { cin >> numS; vector<Teacher> teachers(numT); map<string, int> id_to_index; // 读取教师信息 for (int i = 0; i < numT; ++i) { cin >> teachers[i].id >> teachers[i].name; getline(cin, teachers[i].major); // 去除专业前面的空格 teachers[i].major = teachers[i].major.substr(1); id_to_index[teachers[i].id] = i; } // 处理投票 string ballot; for (int i = 0; i < numS; ++i) { cin >> ballot; if (ballot.length() != 20) continue; vector<bool> used(numT, false); bool valid = true; // 检查选票有效性 for (int rank = 0; rank < 10; ++rank) { string id = ballot.substr(rank*2, 2); if (id == "00") continue; map<string, int>::iterator it = id_to_index.find(id); if (it == id_to_index.end() || used[it->second]) { valid = false; break; } used[it->second] = true; } if (!valid) continue; // 统计有效选票 for (int rank = 0; rank < 10; ++rank) { string id = ballot.substr(rank*2, 2); if (id == "00") continue; int idx = id_to_index[id]; teachers[idx].votes++; teachers[idx].vote_counts[rank]++; teachers[idx].score += scores[rank]; } } // 排序教师 sort(teachers.begin(), teachers.end(), compareTeachers); // 输出前10名 for (int i = 0; i < min(10, numT); ++i) { const Teacher &t = teachers[i]; cout << left << setw(3) << i+1 << setw(4) << t.id << setw(16) << t.name << setw(38) << t.major << setw(7) << t.score << setw(7) << t.votes; for (int j = 0; j < 10; ++j) { cout << setw(7) << t.vote_counts[j]; } cout << "\n"; } } return 0; }
代码说明
- 全局变量:定义了数组
scores
用于存储每个排名位置对应的得分,函数ws
用于计算数字的位数,结构体teacher
用于存储教师信息,变量numT
和numS
分别表示教师数量和学生投票数量,数组ids
用于快速查找教师编号对应的结构体索引。 - 初始化函数
init
:将ids
数组初始化为 ,将每个教师的总票数、总得分和每个排名位置的得票数清零,并读取教师的编号、姓名和专业,同时将教师编号与结构体索引对应存储在ids
数组中。 - 比较函数
compare
:定义了教师结构体的比较规则,用于排序。 - 合法性检查函数
isFei
:检查投票字符串是否合法,即每个教师编号是否存在且未被重复投票。 - 投票解析函数
parse
:解析投票字符串,更新教师的总票数、每个排名位置的得票数以及总得分。 - 主函数
main
:循环读取教师数量和学生投票数量,调用init
函数初始化教师信息,读取学生的投票信息并调用parse
函数进行解析,对教师进行排序,最后输出排名前 名教师的详细信息。
- 1
信息
- ID
- 356
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 3
- 已通过
- 1
- 上传者