PAT 甲级测试题目 -- 1012 The Best Rank

题目链接

题目描述

输入小于等于 2000 的数据 N,M,分别表示 学生的总数 和 查询学生的数量
输入 N 个学生的六位数 id 以及 C,M,E 三科成绩。输入 M 个查询学生的 id。
要求输出:
若被查询的 id 不存在,输出 N/A
若被查询的 id 存在,输出 C,M,E,A(average 平均分) 四个成绩中排名最高的排名,以及对应的分数类型(C, M, E, A)。若有多余一个类型的分数相同,则按照 A > C > M > E 的优先序列输出 排名 和 分数类型

分析

由于各类成绩和学生 id 是对应关系,所以我想到使用 map<string, vector>类型存储录入的数据。
由于要统计各类成绩排名,而且时间限制在 200ms,所以我想用空间换时间,定义了四个数组分别存储 C,M,E,A 四种类型的成绩。
因为考虑到如果成绩相同,则排名相同,下一个排名为上一个的排名加上人数。例如对于 A 类型分数,100分 的有 2 人,99 分的有 1 人,则 100 分的两人排名均为 1,99 分的 1 人排名为 3。
所以对于存储成绩的四个数组,先存储人数,然后根据人数更新排名。
最后遍历的时候,对于每个学生的 vector,根据上述的四个数组确定最高的 排名 以及对应的 分数类型。
最多共需要 32000 + 100 + 42000 = 14100 次循环。
看了其他博主的解析,有用结构体实现的,不知道效率如何,我这边的代码跑了 16ms

实现

#include<iostream>
#include<map>
#include<vector>
#include<string>
#include<string.h>
using namespace std;
int main() {
    // 存储学生总数 和 被检查的学生数量
    int total_students, checked_students;

    // 存储输入的学生信息,string 存储姓名,vector 存储成绩
    map<string, vector<int>> students;

    // 存储 C, M, E, A 四门科目成绩对应的人数,然后使用算法计算成绩对应的排名
    int C[101], M[101], E[101], A[101];

    // 初始化 C, M, E, A 四门科目成绩对应的人数为 0
    memset(C, 0, sizeof(C));
    memset(M, 0, sizeof(M));
    memset(E, 0, sizeof(E));
    memset(A, 0, sizeof(A));

    // 存储存储学生总数 和 被检查的学生数量
    cin >> total_students >> checked_students;

    // 初始化学生信息
    for (int i = 0; i < total_students; i++) {
        // 记录学生的 id
        string student_id; 

        // 记录学生的成绩
        int grade, average = 0;
        vector<int> grades;

        // 输入学生 id
        cin >> student_id;

        // 输入学生成绩
        for (int j = 0; j < 3; j++) {
            cin >> grade;
            grades.push_back(grade);
            average += grade;

            // 记录三科成绩的人数
            if (j == 0)
                C[grade]++;
            if (j == 1)
                M[grade]++;
            if (j == 2)
                E[grade]++;
        }
        // 记录平均成绩
        A[average / 3]++;

        // 插入平均成绩到最前面,方便按照题意中的优先级给出 rank
        grades.insert(grades.begin(), average / 3);

        // 插入学生信息
        students.insert(pair<string, vector<int>>(student_id, grades));
    }

    // 根据录入的三科成绩人数计算排名
    int rankC, rankM, rankE, rankA;
    rankC = rankM = rankE = rankA = 1;

    // 用于交换数据
    int temp;
    for (int i = 100; i >= 0; i--) {
        // 更新 C 排名
        temp = C[i];
        if (temp != 0) {
            C[i] = rankC;
            rankC += temp;
        }

        // 更新 M 排名
        temp = M[i];
        if (temp != 0) {
            M[i] = rankM;
            rankM += temp;
        }

        // 更新 E 排名
        temp = E[i];
        if (temp != 0) {
            E[i] = rankE;
            rankE += temp;
        }

        // 更新 A 排名
        temp = A[i];
        if (temp != 0) {
            A[i] = rankA;
            rankA += temp;
        }
    }

    // 查找学生成绩
    for (int i = 0; i < checked_students; i++) {
        // 记录要查找的学生 id
        string id;
        cin >> id;      

        // 如果找不到该学生
        if (students.count(id) == 0) {
            cout << "N/A";
        }

        // 如果找到了
        else {
            // 定义 char 数组方便输出科目
            char subject[4] = { 'A', 'C', 'M', 'E' };

            // 定义 int 变量方便输出科目
            int index, search_index = 0;

            // 记录排名第一的科目以及科目的成绩,记录成绩方便从成绩表中查到排名
            int topRank = 2001, rankGrade;

            // 迭代器遍历 vector 容器,查询对应学生的每个科目的成绩
            for (vector<int>::iterator iter = students[id].begin(); iter != students[id].end(); iter++) {
                // 记录成绩
                rankGrade = *iter;              

                // 对每个科目进行查找
                if (search_index == 0) {
                    if (topRank > A[rankGrade]) {
                        topRank = A[rankGrade];
                        index = 0;
                    }
                }                   

                if (search_index == 1) {
                    if (topRank > C[rankGrade]) {
                        topRank = C[rankGrade];
                        index = 1;
                    }
                }

                if (search_index == 2) {
                    if (topRank > M[rankGrade]) {
                        topRank = M[rankGrade];
                        index = 2;
                    }
                }

                if (search_index == 3) {
                    if (topRank > E[rankGrade]) {
                        topRank = E[rankGrade];
                        index = 3;
                    }
                }

                // 查找下一个科目
                search_index++;
            }

            cout << topRank << " " << subject[index];
        }
        // 控制格式输出
        if (i != checked_students - 1)
            cout << endl;
    }
    return 0;
}

希望能帮到大家!

原文地址:https://www.cnblogs.com/Breathmint/p/10293400.html

时间: 2024-08-29 20:10:39

PAT 甲级测试题目 -- 1012 The Best Rank的相关文章

PAT 甲级测试题目 -- 1009 Product of Polynomials

题目链接 这题占个坑吧...我用了两种思路,一种将保存结果的数组初始化为 0,把乘积加上去,顺便记录下最后一个指数的值.用两次 2000 次 for 循环过滤掉 0 值以及输出答案,这个代码过了,但是后期测试的时候,有些测试用例会多出来空格,有些则格式不对..但是过了... 代码如下 #include<iostream> #include<stdio.h> using namespace std; int main() { double A[1001], B[1001]; int

PAT 甲级测试题目 -- 1010 Radix

题目链接 题目描述 给你两个数以及其中一个数的基数(进制数),找出另一个数的基数,找不到就输出 Impassible 分析 思路不是很难,基本可以用进制转换加循环判断做,但是有坑... 坑1:上界不是36....上界是确定的那个数的十进制加 1 . 坑2:暴力循环会导致时间超限,用二分法解决 坑3:二分过程中会有数据溢出,得到的负数处理方式和找到较大数处理方式一样,因为溢出的数和题目条件不符,所以可以舍弃. 实现 #include<iostream> #include<string.h&

PAT 甲级测试题目 -- 1013 Battle Over Cities

题目链接 题目描述 ??给你城市的数量 N(N<1000),城市中地铁的数量 M 以及 被可能占领的城市数量 K(每一次只占领一个城市,并且每次占领的城市不一样),接下来的 M 行根据地铁的数量给出每个地铁连接的两个城市编号.最后一行给你被占领的城市序列.城市编号为 1 到 N,请你求出若某个城市被占领了,连通剩下城市所需要修建的地铁个数. 分析 ??该题考察图的存储以及遍历.本题的难点在于把 "需要维修多少个地铁" 这个问题转换成 "需要多少次 dfs 才能遍历完整个

pat 甲级测试题目 -- 1016 Phone Bills

题目链接 题目描述 要求计算银行账单. 输入 第一行给你一天24小时(00:00~01:00 ...)每个小时每分钟的话费,单位是美分 第二行给你顾客列表(N 个) 接下来的 N 行是顾客的账单详情 CYLL 01:01:06:01 on-line 姓名 月:日:小时:分钟 状态 CYLL 01:28:16:05 off-line 姓名 月:日:小时:分钟 状态 on-line 和 off-line 必须一一对应该记录才有效 输出 对于输入有效的顾客,给出该顾客这个月的账单,格式如下 CYJJ

PAT甲题题解-1012. The Best Rank (25)-排序水题

排序,水题因为最后如果一个学生最好的排名有一样的,输出的课程有个优先级A>C>M>E那么按这个优先级顺序进行排序每次排序前先求当前课程的排名然后再与目前最好的排名比较.更新 至于查询,建立id与索引的映射即可. #include <iostream> #include <algorithm> #include <cstdio> #include <cstring> #include <map> using namespace s

PAT——甲级1012:The Best Rank

1012 The Best Rank (25 point(s)) To evaluate the performance of our first year CS majored students, we consider their grades of three courses only: C - C Programming Language, M - Mathematics (Calculus or Linear Algrbra), and E - English. At the mean

1012. The Best Rank (25)——PAT (Advanced Level) Practise

题目信息: 1012. The Best Rank (25) 时间限制 400 ms 内存限制 32000 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue To evaluate the performance of our first year CS majored students, we consider their grades of three courses only: C - C Programming Language, M - Math

PAT 1012. The Best Rank (25)

1012. The Best Rank (25) To evaluate the performance of our first year CS majored students, we consider their grades of three courses only: C - C Programming Language, M - Mathematics (Calculus or Linear Algebra), and E - English. At the mean time, w

pat甲级1012

1012 The Best Rank (25)(25 分) To evaluate the performance of our first year CS majored students, we consider their grades of three courses only: C - C Programming Language, M - Mathematics (Calculus or Linear Algebra), and E - English. At the mean ti