算法初步-排序:PAT A1075 PAT Judge (25 分)

算法初步-排序:PAT A1075 PAT Judge (25 分)

题目

The ranklist of PAT is generated from the status list, which shows the scores of the submissions. This time you are supposed to generate the ranklist for PAT.
Input Specification:
Each input file contains one test case. For each case, the first line contains a positive integer K (≤20) which is the number of repeat times. Then the next line contains the given order. All the numbers in a line are separated by a space.

Output Specification:
For each test case, you are supposed to output the ranklist in the following format:

rank user_id total_score s[1] … s[K]

where rank is calculated according to the total_score, and all the users with the same total_score obtain the same rank; and s[i] is the partial score obtained for the i-th problem. If a user has never submitted a solution for a problem, then “-” must be printed at the corresponding position. If a user has submitted several solutions to solve one problem, then the highest score will be counted.

The ranklist must be printed in non-decreasing order of the ranks. For those who have the same rank, users must be sorted in nonincreasing order according to the number of perfectly solved problems. And if there is still a tie, then they must be printed in increasing order of their id’s. For those who has never submitted any solution that can pass the compiler, or has never submitted any solution, they must NOT be shown on the ranklist. It is guaranteed that at least one user can be shown on the ranklist.

Sample Input:

7 4 20
20 25 25 30
00002 2 12
00007 4 17
00005 1 19
00007 2 25
00005 1 20
00002 2 2
00005 1 15
00001 1 18
00004 3 25
00002 2 25
00005 3 22
00006 4 -1
00001 2 18
00002 1 20
00004 1 15
00002 4 18
00001 3 4
00001 4 2
00005 2 -1
00004 2 0

Sample Output:

1 00002 63 20 25 - 18
2 00005 42 20 0 22 -
2 00007 42 - 25 - 17
2 00001 42 18 18 4 2
5 00004 40 15 0 25 -

题解

马上要院赛啦,其实也没有几天,找找感觉吧!可以说这道排序题目也是给了我很大的警醒,要认真!要加油!要有自信!
下面就是最终的AC啦:

#include<iostream>
#include<algorithm>
#include<vector>
#include<string>
using namespace std;

struct node{
    int id;
    int rank;
    int total_grade;//总分数
    int grade[5];
    int full_number;//满分题目数
    bool flag;
    //node(int total_grade,int full_number):total_grade(0),full_number(0){}
};

bool cmp(struct node a , struct node b){
    if(a.total_grade != b.total_grade)
        return a.total_grade > b.total_grade;
    else if(a.full_number != b.full_number)
        return a.full_number > b.full_number;
    else
        return a.id < b.id;
}

int main()
{
    int people_number;//总人数
    int course_number;//课程数
    int submit_number;//提交数
    
    cin >> people_number >> course_number >> submit_number;
    
    //初始化每人的每题分数
    struct node nb[people_number];
    for(int i =0 ;i < people_number ;i++){
        nb[i].flag = false;
        nb[i].id = i + 1;
        nb[i].full_number = 0;
        nb[i].total_grade = 0;
        for(int j =0 ;j < course_number ;j++){
            nb[i].grade[j] = -1;
        }
    }
    
    //读取每题满分值
    int full_grade[course_number];
    for(int i = 0 ;i < course_number ;i++){
        cin >> full_grade[i];
    }
    
    string str;
    int cnt;
    int temp;
    for(int i = 0 ;i < submit_number ;i++){
        cin >> str >> cnt >> temp;
        if(temp == full_grade[cnt - 1] && nb[stoi(str) - 1].grade[cnt-1] != full_grade[cnt - 1])
            nb[stoi(str) - 1].full_number++;//满分题目数加一
        if(temp >= 0) nb[stoi(str) - 1].flag = true;
        if(temp == -1) temp = 0;
        if(temp > nb[stoi(str) - 1].grade[cnt - 1])
            nb[stoi(str) - 1].grade[cnt - 1] = temp;
    }
    
    //计算总分
    for(int  i = 0 ; i< people_number ;i++){
        for(int j =0 ;j < course_number ;j++){
            if(nb[i].grade[j] > 0)
                nb[i].total_grade += nb[i].grade[j];
        }
//         cout << nb[i].total_grade << " ";
    }
//     cout << endl;
    
        //跟踪数据输出,确保正确
//     for(int i =0 ;i < people_number ;i++){
//         cout << nb[i].full_number << " ";
//         for(int j =0 ;j < course_number ;j++){
//             cout << nb[i].grade[j]  << " ";
//         }
//         cout << endl;
//     }
    
    sort(nb,nb+people_number,cmp);
    nb[0].rank = 1;
    for(int i = 1 ; i < people_number ; i++){
        if(nb[i].total_grade == nb[i-1].total_grade)
            nb[i].rank = nb[i-1].rank;
        else
            nb[i].rank = i + 1;
    }
    
    for(int i = 0 ; i < people_number ; i++){
        if(nb[i].flag){
            cout << nb[i].rank << " ";
            printf("%05d",nb[i].id);
            cout << " " << nb[i].total_grade << " ";
            for(int j = 0 ; j < course_number ; j++){
                if(j != 0) cout << " ";
                
                if(nb[i].grade[j] != -1)
                    cout << nb[i].grade[j];
                else
                    cout << "-";
            }
            cout << endl;
        }
    }
    return 0;
}

<一>、第一次运行代码
开始跑的时候只能过一个测试点,也就是第一个啦,13point。然后找了问题,发现我把cmp排序函数索引定死啦,给的样例是7个人数,但是不能按照一般情况来呀,改成了people_number后,以为没问题啦,结果只能多对啦一个测试点,有点失望,不过没关系,接着寻找问题。

sort(nb,nb+people_number,cmp);

<二>、继续排错
观察到输出会有学生的学号,我最初是先输出四个0,然后加上个位的数字,导致大于10的学号输出不正确,接着把id输出格式修改啦,又对了一个测试点hhh:

printf("%05d",nb[i].id);

<三>、接着看了好久开始求助CSDN
发现了一个题目我的理解错误:最终总成绩为0的情况有三种:一次都没有提交;提交答案但是没有通过编译;通过编译但是测试点没有通过;三者中只有最后一种情况才可以输出。
因为题解中读取到-1的时候要不要转换成0是一个卡点的问题,如果当时转化成0,后面将不太好判断是否输出该学生的成绩信息(因为可能出现该学生所有提交均没有通过编译,该情况不能输出的);如果不转换成0,最后的输出会出现问题(因为未通过编译的题目分数最后输出显示为0)。
想了会,再加个标志位吧,读取数据是-1的时候还是转换成0,但不过在转换成0之前,先判断分数中是否存在>=0的情况,一旦检测出有分数>=0,则说明存在学生提交题目答案通过测试点,但是没有通过测试点,这种情况属于上面说的三者最后一条,应该输出显示排名。

for(int i = 0 ;i < submit_number ;i++){
        cin >> str >> cnt >> temp;
        if(temp == full_grade[cnt - 1] && nb[stoi(str) - 1].grade[cnt-1] != full_grade[cnt - 1])
            nb[stoi(str) - 1].full_number++;
        //判断!
        if(temp >= 0) nb[stoi(str) - 1].flag = true;
        if(temp == -1) temp = 0;
        if(temp > nb[stoi(str) - 1].grade[cnt - 1])
            nb[stoi(str) - 1].grade[cnt - 1] = temp;
    }

<四>、还是有一个测试点没有通过
不禁要感慨这道题真细节啊,平时不管是学习还是生活也要学习这种认真仔细地方式:
后面检查到在判断满分题目数量的时候,可能会出现满分多次提交的情况,这种情况就会导致满分题目数量判断不准,所以我们在加一操作的时候增加判断条件:

//当现有的分数小于要存的分数并且现有的分数不是满分时候更新++
if(temp == full_grade[cnt - 1] && nb[stoi(str) - 1].grade[cnt-1] != full_grade[cnt - 1])
            nb[stoi(str) - 1].full_number++;//满分题目数加一

晚安,送自己也是大家的一句话:在内卷的时代要学会深耕自己!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

浪漫世界值得孤身qwq

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值