【ACM】PAT. A1075. PAT Judge【排序】

题目链接
题目分析

【排名规则】总分相同 则 名次相同

【输出顺序 排序规则】总分、完美解决问题数 、id

【输出要求】

  • 没有提交的题目输出 '-'(没通过编译的也算提交)
  • 没有 有效提交user不输出(总分为0也输出)
解题思路

结构体排序解决即可
【注意点】

  • 可能有多次AC提交,不要重复记录 “完美解决数”
  • 通过编译,总分为0也要输出
  • 排序时,利用有效提交属性,否则零分user可能排在无效user后面

AC程序(C++)
/**************************
*@Author: 3stone
*@ACM: PAT.A1075 PAT Judge
*@Time: 18/7/20
*@IDE: VSCode 2018
***************************/
#include<cstdio>
#include<algorithm>
#include<cstring>

using namespace std;

#define maxn 10010

struct User {
    int id, total_score; //序号,总分
    int partial_score_obtained[10]; //每道题的得分
    bool flag[10]; //某道题是够有提交
    bool success_submit;//此学生是够有有效提交
    int perfectly_solved_num; //完美解决问题数目
}user[maxn];

//比较函数
bool cmp(User a, User b) {
    //记得加这第一条规则,否则零分`user`可能排在无效`user`后面
    if(a.success_submit != b.success_submit) return a.success_submit > b.success_submit;
    else if(a.total_score != b.total_score)
        return a.total_score > b.total_score;
    else if(a.perfectly_solved_num != b.perfectly_solved_num)
        return a.perfectly_solved_num > b.perfectly_solved_num;
    else
        return a.id < b.id;
}

//标记排名 + 输出函数  (两个参数需以 引用 形式传递)
void myPrint(int id, int& rank, int& pre_total_score, int pro_num){
    if(pre_total_score != user[id].total_score)
        rank = id + 1;
    pre_total_score = user[id].total_score; //记录前者分数,以便分数相同,排名相同

    printf("%d %05d %d", rank, user[id].id, user[id].total_score);
    for(int j = 1; j <= pro_num; j++){
        if(user[id].flag[j]) //此题有提交
            printf(" %d", user[id].partial_score_obtained[j]);
        else
            printf(" -");
    }
    printf("\n");
}

int main() {

    int user_num, pro_num, sub_num;
    int temp_id, temp_pro, temp_score;

    while(scanf("%d%d%d", &user_num, &pro_num, &sub_num) != EOF) {

        for(int i = 0; i < maxn; i++){ //初始化
            user[i].total_score = 0;
            user[i].success_submit = false;
            user[i].perfectly_solved_num = 0;
            memset(user[i].flag, false, sizeof(user[i].flag)); //初始均 无提交
            memset(user[i].partial_score_obtained, 0, sizeof(user[i].partial_score_obtained)); //初始 分数为0
        }

        int pro_full_mark[10]; //问题总分
        for (int i = 1; i <= pro_num; i++) {
            scanf("%d", &pro_full_mark[i]);
        }
        for (int i = 0; i < sub_num; i++) {
            scanf("%d%d%d", &temp_id, &temp_pro, &temp_score);

            user[temp_id].id = temp_id;
            user[temp_id].flag[temp_pro] = true; //标记该题目有提交记录

            if(temp_score >= 0) //有效提交
                user[temp_id].success_submit = true;

            //完美解决方案 //条件2:保证针对本题的多次完美提交只计数一次
            if(temp_score == pro_full_mark[temp_pro] && user[temp_id].partial_score_obtained[temp_pro] < temp_score)  
                user[temp_id].perfectly_solved_num++;

            if(temp_score > user[temp_id].partial_score_obtained[temp_pro]) { //新提交 分数 更高
                //更新总分数
                user[temp_id].total_score -= user[temp_id].partial_score_obtained[temp_pro];
                user[temp_id].total_score += temp_score;
                //更新该题目得分
                user[temp_id].partial_score_obtained[temp_pro] = temp_score;
            }
        }//for

        sort(user, user + maxn, cmp);

        //输出
        int rank = 1, pre_total_score = user[0].total_score;
        myPrint(0, rank, pre_total_score, pro_num);
        for(int i = 1; ; i++) {
            if(user[i].success_submit){
                myPrint(i, rank, pre_total_score, pro_num);
            }
            else
                break;
        }

    }//while

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值