1 条题解

  • 1
    @ 2025-5-6 1:00:41

    题目分析

    题意简述

    本题涉及对教师信息的处理和排名。输入包括教师数量 numTnumT 和学生投票数量 numSnumS。对于每个教师,有编号 idid、姓名 namename、专业 majormajor,以及他们获得的投票信息。学生的投票信息是一个字符串,代表他们对教师的排名。程序需要根据投票信息计算每个教师的得分和投票数,并按照特定规则进行排名,最后输出排名前 1010 名教师的详细信息。

    输入

    • 多组测试用例。每组测试用例首先输入教师数量 numTnumT 和学生投票数量 numSnumS
    • 接着输入每个教师的编号 idid、姓名 namename 和专业 majormajor
    • 然后输入每个学生的投票信息,是一个字符串,其中每两个字符表示一个教师的编号,代表该教师在学生心中的排名。

    输出

    对于每组测试用例,输出排名前 1010 名教师的详细信息,包括排名、编号、姓名、专业、得分、投票数以及在每个排名位置上的得票数。


    解题思路

    初始化

    1. 定义教师结构体 teacher,包含编号 id、姓名 name、专业 major、总票数 votes、总得分 score 以及每个排名位置的得票数 vote[10]
    2. 定义数组 ids 用于快速查找教师编号对应的结构体索引,初始化为 1-1
    3. 初始化教师信息,包括将每个教师的总票数、总得分和每个排名位置的得票数清零,并读取教师的编号、姓名和专业,同时将教师编号与结构体索引对应存储在 ids 数组中。

    投票解析

    1. 定义函数 isFei 用于检查投票字符串是否合法。遍历投票字符串,检查每个教师编号是否存在且未被重复投票。
    2. 定义函数 parse 用于解析投票字符串。如果投票字符串合法,则遍历字符串,根据教师编号找到对应的教师结构体,更新其总票数、每个排名位置的得票数以及总得分。

    排名与输出

    1. 定义比较函数 compare,用于对教师结构体进行排序。排序规则为:总得分高的教师排在前面;如果总得分相同,则总票数多的教师排在前面;如果总得分和总票数都相同,则编号小的教师排在前面。
    2. 读取学生的投票信息,并调用 parse 函数进行解析。
    3. 对所有教师进行排序。
    4. 输出排名前 1010 名教师的详细信息,包括排名、编号、姓名、专业、得分、投票数以及在每个排名位置上的得票数。输出时注意格式对齐。

    代码实现

    #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;
    }
    

    代码说明

    1. 全局变量:定义了数组 scores 用于存储每个排名位置对应的得分,函数 ws 用于计算数字的位数,结构体 teacher 用于存储教师信息,变量 numTnumS 分别表示教师数量和学生投票数量,数组 ids 用于快速查找教师编号对应的结构体索引。
    2. 初始化函数 init:将 ids 数组初始化为 1-1,将每个教师的总票数、总得分和每个排名位置的得票数清零,并读取教师的编号、姓名和专业,同时将教师编号与结构体索引对应存储在 ids 数组中。
    3. 比较函数 compare:定义了教师结构体的比较规则,用于排序。
    4. 合法性检查函数 isFei:检查投票字符串是否合法,即每个教师编号是否存在且未被重复投票。
    5. 投票解析函数 parse:解析投票字符串,更新教师的总票数、每个排名位置的得票数以及总得分。
    6. 主函数 main:循环读取教师数量和学生投票数量,调用 init 函数初始化教师信息,读取学生的投票信息并调用 parse 函数进行解析,对教师进行排序,最后输出排名前 1010 名教师的详细信息。
    • 1

    信息

    ID
    356
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    3
    已通过
    1
    上传者