PAT Advanced Level 1075. PAT Judge (25)

【来源】

1075. PAT Judge (25)

【分析】

    本题模拟的是PAT的评分和排名系统。

    做这种给出的信息很大,要求很多的题目时,我采用的策略一般是渐进式编程。刚开始码代码时,不必将所有的条件都考虑在内,只关心大致的框架和逻辑。完成框架以后再逐步完善细节。因此以下的解题思路并非一开始就是这么想的,而是后验的,考虑的细节已经比较全面了。

    具体解题思路如下:

    首先建立起考生数据模型(struct),包含的信息有考生的id、每道题所得到的分数、得到的总分、排名、该记录是否有效、完美解决问题的数量以及提交次数。初始化时,将考生每题的得分初始化为-1,代表该考生未进行任何提交。

    然后依据排名规则写出compare函数来对考生进行sort。具体规则为:首先按总分降序排名,总分一样的话按照完美解决问题的个数降序排名,个数一样的再按照id升序排名。

    考虑到考生的数量在10000以内,所以开一个长度为10001的vector。对于每次提交,如果发现编译错误(partialscore为-1),此题不得分;否则记有效提交次数加1。如果此次提交的题目比上次分数高,则更新该考生的此题分数,并且如果此题分数达到满分,记完美解决的问题数加1。

    经过上一轮之后,接下来我们需要把有效的记录提取出来,并且把从未进行过任何有效提交的考生排除出去,顺便计算出考生的总分。

    之后开始根据刚开始写好的compare函数对考生进行排序。需注意总分相同的考生名次应该相同。

    排序之后输出。对于考生没有提交过的题目(得分为-1),输出“-”即可。

【代码】

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

struct User{
    int id;
    int scores[5];
    int totalscore;
    int rank;
    bool valid;
    int perfect;
    int submits;
    User(){
        valid = false;
        rank = 0;
        totalscore = 0;
        for (int i = 0; i < 5; ++i){
            scores[i] = -1;
        }
        perfect = 0;
        submits = 0;
    }
};

bool compare(User u1, User u2){
    if (u1.totalscore != u2.totalscore){
        return u1.totalscore > u2.totalscore;
    }
    else{
        if (u1.perfect != u2.perfect){
            return u1.perfect > u2.perfect;
        }
        else{
            return u1.id < u2.id;
        }
    }

}
int main()
{
    int N, K, M;
    scanf("%d%d%d", &N, &K, &M);
    int *p = new int[K];
    for (int i = 0; i < K; ++i){
        scanf("%d", &p[i]);
    }
    vector<User> users(10001);
    for (int i = 0; i < M; ++i){
        int user_id, problem_id, partial_score;
        scanf("%d%d%d", &user_id, &problem_id, &partial_score);
        users[user_id].id = user_id;
        users[user_id].valid = true;
        if (partial_score == -1){
            partial_score = 0;
        }
        else{
            ++users[user_id].submits;
        }
        if (partial_score > users[user_id].scores[problem_id - 1]){
            users[user_id].scores[problem_id - 1] = partial_score;
            if (partial_score == p[problem_id - 1]){
                ++users[user_id].perfect;
            }
        }
    }
    
    vector<User> dense;
    for (int i = 0; i < 10001; ++i){
        if (users[i].valid){
            for (int j = 0; j < K; ++j){
                if (users[i].scores[j] != -1){
                    users[i].totalscore += users[i].scores[j];
                }
            }
            if (users[i].submits > 0){
                dense.push_back(users[i]);
            }
        }
    }

    sort(dense.begin(), dense.end(), compare);

    dense[0].rank = 1;
    for (int i = 1; i < dense.size(); ++i){
        dense[i].rank = i + 1;
        if (dense[i].totalscore == dense[i-1].totalscore){
            dense[i].rank = dense[i-1].rank;
        }
    }

    for (int i = 0; i < dense.size(); ++i){
        printf("%d %05d %d", dense[i].rank, dense[i].id, dense[i].totalscore);
        for (int j = 0; j < K; ++j){
            if (dense[i].scores[j] != -1){
                printf(" %d", dense[i].scores[j]);
            }
            else{
                printf(" -");
            }
        }
        printf("\n");
    }

    delete[] p;
    system("pause");
    return 0;
}

【点评】

此题要求甚多且有陷阱,考察较高水平的抽象能力和问题解决能力。需注意区分提交答案错误与没有进行有效提交(即通过编译器的提交)是有区别的。不注意这种区别就会掉入陷阱。


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值