【PAT】1075 PAT Judge (25 分)

46 篇文章 0 订阅
44 篇文章 0 订阅
该博客介绍了如何处理PAT编程比赛的提交状态,生成排名列表。重点在于使用结构体存储用户信息,通过排序算法实现按分数和满分题目数量进行排名。代码中涉及结构体、vector和sort等知识,确保至少有一个用户出现在排名列表中。
摘要由CSDN通过智能技术生成
  • 题目大意:根据提交的状态列表,生成PAT的排名列表。

    • 若提交不成功,显示为为-1,实际得分为0;若提交成功,显示为[0, p[pid]]。(注意:若用户提交成功但是没编译通过,虽然显示的是-1,但要把分数赋值为0。我之前读错题了,以为得分是-1)。

    • 结果按总分排名,若总分相同则排名相同。排名和id后面跟着各题的分数(未提交为’-’,提交多次为最高分)。

    • 输出按排名升序。若排名相同,就按满分题目的个数降序排。若还相同,就按id升序排。

    • 没提交成功过或没有提交过的人不进行排名(即成绩为-1均为或没提交过题目的人)。注意:保证排名列表里最少有一个人。

  • 思路:用结构体存储用户的信息,然后进行排序。

    1. 用flag记录该用户是否提交过可通过的答案。将每个人的各题的成绩初始化为0,总成绩都初始化为-1(因为还要考虑只有一个学生,且总分为0的情况)。每次输入成绩时,都比较大小,若比原有成绩大,就更新成绩。(注意:因为若用户提交成功但是没编译通过,虽然显示的是-1,但要把分数赋值为0

    2. 得分数组应该先初始化为-1,-1未编译成功或者没提交过的题目。

    3. 结构体里记录满分题的个数,方便后面排序,之后还需在一个循环里统计满分提的个数

    4. 输出按排名升序,即按总分降序。若总分相同,就按满分题目的个数降序排。若还相同,就按id升序排。

      遇到flag为false的跳过。

  • 知识点:

    1. 结构体
    2. vector
    3. sort
  • 代码:

    #include <iostream>
    #include <vector>
    #include <algorithm>
    using namespace std;
    
    struct user{
        bool flag = false;
        int id, total = -1, cnt = 0; // cnt记录满分题的个数
        int p[6] = {-1, -1, -1, -1, -1, -1}; //数组记录该用户每题的得分
    };
    
    int count(user u, int k, int* p){
        int cnt = 0;
        for(int i = 1; i <= k; i++) // 注意i从1开始
            if(u.p[i] == p[i])
                cnt++;
        return cnt;
    }
    
    int sumScore(user u, int k){
        int sum = 0, cnt = 0;   // cnt记录未通过/没做过的题目个数
        for(int i = 1; i <= k; i++) // 注意i从1开始
            if(u.p[i] != -1)
                sum += u.p[i];
            else
                cnt++;
        if(cnt == k)
            sum = -1;
        return sum;
    }
    
    bool cmp(user a, user b){
        if(a.total != b.total)
            return a.total > b.total;
        else{
            return a.cnt != b.cnt ? a.cnt > b.cnt : a.id < b.id;
        }
    }
    
    int main()
    {
        int n, k, m;
        scanf("%d %d %d", &n, &k, &m);
        int p[6] = {0};
        vector<user> v(10001);
    //    user temp;
    
        for(int i = 1; i <= k; i++) // 注意题目id是从1开始的
            scanf("%d", p + i);
        // 将id、各题分数、总分输入user数组
        for(int i = 0; i < m; i++){
            int id, index, score;
            scanf("%d %d %d", &id, &index, &score);
            v[id].id = id;
            if(score != -1)
                v[id].flag = true;
            if(score == -1 && v[id].p[index] == -1)
                v[id].p[index] = 0;
            else if(score > v[id].p[index])
                v[id].p[index] = score;
        }
        // 统计每个用户满分题的个数和总分
        for(int i = 1; i <= n; i++){
            v[i].cnt = count(v[i], k, p);
            v[i].total = sumScore(v[i], k);
        }
        sort(v.begin(), v.end(), cmp);
    
        int rank = 0, temp_rank = 0, total = -1;    // 注意total初始化为-1,
        for(int i = 0; i < n; i++){
            if(v[i].flag == false)
                continue;
            else{
                rank++;
                if(v[i].total != total){
                    total = v[i].total;
                    temp_rank = rank;
                }
                printf("%d %05d %d", temp_rank, v[i].id, v[i].total);
                for(int j = 1; j <= k; j++){
                    if(v[i].p[j] == -1)
                        printf(" -");
                    else
                        printf(" %d", v[i].p[j]);
                }
                printf("\n");
            }
        }
        return 0;
    }
    
  • 总结:

    1. 可以用一个bool变量flag记录用户是否提交过代码或编译成功过代码,这样就可以在输出时判断是否要输出该用户信息。
    2. 粗心:
      1. 读题不仔细:
        1. 注意题目id和用户id都是从1开始的;
        2. 若用户提交成功但是没编译通过,虽然显示的是-1,但要把分数赋值为0;
        3. “It is guaranteed that at least one user can be shown on the ranklist.” 表示还要考虑只有一个用户,但得分全是0的情况。要把total初始化为-1。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值