Skip to content

14201: 【原4201】成绩统计

题目

题目描述

author: 程序设计思想与方法助教组李泽仁王志伟 原OJ链接:https://acm.sjtu.edu.cn/OnlineJudge-old/problem/4201 ## 问题描述 每次全校程序设计思想与方法考试结束后,考试中心都会发布一个考生学院排行榜。本题就请你实现这个功能。

输入输出描述

输入

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

    准考证号 得分 学院

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

输出

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

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

其中排名是该学院的排名(从 1 开始);学院是全部按小写字母输出的单位码;加权总分定义为 $$ 乙级总分/1.5 + 甲级总分 + 顶级总分1.5 $$ 的整数部分(友情提醒:浮点数存在截断误差)考生人数*是该属于学院的考生的总人数。

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

要求

为方便检验你面向对象编程的能力,现提供相关类声明和主函数以供参考。类的声明可以不一样,但要求使用给出的主函数完成程序设计,不要另外编写主函数

struct School
{
    char name[7]; //学院名字
    double score; //加权总分
    int count;    //学生人数
};

class Solution
{
public:
    Solution(int cnt) { numOfSchool = 0; schools = new School[cnt];}
    //根据学生信息,修改所在学院的相应信息
    void modify(char* id, double score, char* schoolName); 
    void displayResult();  //输出
          ~School(){ delete []schools;}

  // 可以根据设计自行添加所需成员


private:
    School *schools;    // 存放学院信息的指针
          unsigned int numOfSchool;  // 学院数量

// 可以根据设计自行添加所需成员

};

//main函数不要做任何修改
int main()
{
    int numOfPerson;  
    cin >> numOfPerson;   //输入考试人数

    char id[7]; //准考证号
    int score;  //分数
    char schoolName[7]; //学院名字

    Solution solution(numOfPerson);

    for (int i = 0; i < numOfPerson; i++) {
        cin >> id >> score >> schoolName;    // 读取考试信息
    solution.modify(id, score, schoolName);  //根据学生信息,修改所在学院的相应信息
}
    solution.displayResult();    //输出结果

    return 0;
}

程序运行示例0

Sample Input 0

8
A57908 66 Au
B57908 99 LanX
A37487 60 au
T28374 69 CMU
T32486 24 hypu
A66734 93 cmu
B76378 72 AU
A47780 45 lanx

Sample Output 0

4
1 cmu 196 2
2 au 174 3
3 lanx 111 2
4 hypu 36 1

程序运行示例1

Sample Input 1

10
A57908 66 Au
B57908 99 LanX
A37487 60 au
T28374 69 CMU
T32486 24 hypu
A66734 93 cmu
B76378 72 AU
A47780 45 lanx
A66334 96 HypU
B71378 75 cMU

Sample Output 1

4
1 cmu 246 3
2 au 174 3
3 hypu 132 2
4 lanx 111 2

程序运行示例2

Sample Input 2

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

Sample Output 2

5
1 cmu 192 2
1 au 192 3
3 pku 100 1
4 hypu 81 2
4 lanx 81 2

ligongzzz's solution

#include "iostream"
#include "algorithm"
#include "cstring"
#include "cstdio"
using namespace std;

constexpr double jd = 0.00001;

//交换
template <class T>
void mySwap(T&a, T &b) {
    T temp = a;
    a = b;
    b = temp;
}

struct School
{
    char name[7]; //学院名字
    double score; //加权总分
    int count;    //学生人数

    int scoreA = 0, scoreB = 0, scoreC = 0;
};

class Solution
{
public:
    Solution(int cnt) { numOfSchool = 0; schools = new School[cnt]; }
    //根据学生信息修改所在学院的相应信息
    void modify(char* id, double score, char* schoolName);
    void displayResult();  //输出
    ~Solution() { delete[] schools; }

    // 可以根据设计自行添加所需成员

private:
    School *schools;    // 存放学院信息的指针
    unsigned int numOfSchool;  // 学院数量

// 可以根据设计自行添加所需成员

};
void Solution::displayResult() {
    //算分
    for (int i = 0; i < numOfSchool; i++) {
        schools[i].score = double(schools[i].scoreA) + double(schools[i].scoreB) / 1.5 + double(schools[i].scoreC) * 1.5;
    }

    //开始排序
    sort(schools, schools + numOfSchool, [](School a, School b) {
        return int(a.score) > int(b.score) ||
            int(a.score) == int(b.score) && (a.count < b.count) ||
            (int(a.score) == int(b.score) && (a.count == b.count) && strcmp(a.name, b.name) < 0);
    });
    /*auto num = numOfSchool;
    auto destination = schools;
    for (int i = num - 2; i >= 0; i--)
        for (int j = 0; j <= i; j++)
        {
            bool flag = false;
            if (int(destination[j].score) < int(destination[j+1].score)) flag = true;
            else if (int(destination[j].score) == int(destination[j+1].score) && destination[j].count > destination[j + 1].count) flag = true;
            else if (int(destination[j].score) == int(destination[j+1].score) && destination[j].count == destination[j + 1].count&&strcmp(destination[j].name, destination[j + 1].name) > 0) flag = true;
            if(flag)
               mySwap(destination[j], destination[j + 1]);
        }*/
    cout << numOfSchool;
    for (int i = 0; i < numOfSchool; i++) {
        cout << endl;
        //判断是否并列
        int n = 0;
        for (n = 1; n <= numOfSchool; n++)
            if (int(schools[n - 1].score) == int(schools[i].score))
                break;
        cout << n << " " << schools[i].name << " " << int(schools[i].score) << " " << schools[i].count;
    }
}

void Solution::modify(char* id, double score, char* schoolName) {
    //化小写
    for (int i = 0; i < strlen(schoolName); i++) {
        if (schoolName[i] >= 'A'&&schoolName[i] <= 'Z') {
            schoolName[i] -= 'A' - 'a';
        }
    }
    //归并学院
    bool flag = false;
    int thisSchool = 0;
    for (int i = 0; i < numOfSchool; i++) {
        if (strcmp(schoolName, schools[i].name) == 0) {
            flag = true;
            thisSchool = i;
            break;
        }
    }
    if (!flag) {
        thisSchool = numOfSchool++;
        schools[thisSchool].count = 0;
        schools[thisSchool].score = 0.0;
        strcpy(schools[thisSchool].name, schoolName);
    }

    //开始算分
    schools[thisSchool].count++;
    if (id[0] == 'A') schools[thisSchool].scoreA += score;
    else if (id[0] == 'B') schools[thisSchool].scoreB += score;
    else if (id[0] == 'T') schools[thisSchool].scoreC += score;
}
//main函数不要做任何修改
int main()
{
    int numOfPerson;
    cin >> numOfPerson;   //输入考试人数

    char id[7]; //准考证号
    int score;  //分数
    char schoolName[7]; //学院名字

    Solution solution(numOfPerson);

    for (int i = 0; i < numOfPerson; i++) {
        cin >> id >> score >> schoolName;    // 读取考试信息
        solution.modify(id, score, schoolName);  //根据学生信息修改所在学院的相应信息
    }
    solution.displayResult();    //输出结果

    return 0;
}