• 1075. PAT Judge (25)


    题目如下:

    The ranklist of PAT is generated from the status list, which shows the scores of the submittions. 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 3 positive integers, N (<=104), the total number of users, K (<=5), the total number of problems, and M (<=105), the total number of submittions. It is then assumed that the user id's are 5-digit numbers from 00001 to N, and the problem id's are from 1 to K. The next line contains K positive integers p[i] (i=1, ..., K), where p[i] corresponds to the full mark of the i-th problem. Then M lines follow, each gives the information of a submittion in the following format:

    user_id problem_id partial_score_obtained

    where partial_score_obtained is either -1 if the submittion cannot even pass the compiler, or is an integer in the range [0, p[problem_id]]. 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 -
    


    题目要求对多个用户的PAT成绩进行排序,规则比较繁琐,一定要仔细读题,下面对题目的要点进行分析。

    ①用户的分数以-1标记时代表编译失败,但最后输出时要输出0分,并且如果用户有提交,即使得分为0,只要通过了编译,也要输出,因此-1是一个区分编译成功和失败的重要标志,刚开始不要碰到-1就存入0,这样后面就无法判断0分的情况了。

    ②排序时注意按照总分降序(由排名升序转化而来),总分持平的按照AC题目数的降序,如果继续持平则按照id的升序排列。

    ③注意先排除掉那些从未编译成功或者从未提交过的用户,然后进行排序,最后输出。

    ④注意排名的计算规则。

    代码如下:

    #include <iostream>
    #include <stdio.h>
    #include <vector>
    #include <algorithm>
    #include <memory.h>
    
    using namespace std;
    
    int N,K,M;
    int fullmarks[6];
    struct Person{
    
        int id;
        int scores[6];
        int perfects;
        int sum;
        bool passCompiler;
    
        Person(){
            passCompiler = false;
            for(int i = 0; i < 6; i++) scores[i] = -2;
            perfects = 0;
        }
    
    public:
        void computeSum(){
            sum = 0;
            for(int i = 1; i <= K; i++){
                if(scores[i] < 0) continue;
                passCompiler = true;
                sum += scores[i];
            }
        }
    
        bool operator < (const Person &p1) const{
    
            if(sum < p1.sum) return false;
            else if(sum > p1.sum) return true;
            else{
                if(perfects < p1.perfects) return false;
                else if(perfects > p1.perfects) return true;
                else{
                    return id < p1.id;
                }
            }
    
            return true;
        }
    
    };
    
    int main()
    {
        cin >> N >> K >> M;
        for(int i = 1; i <= K; i++)
            scanf("%d",&fullmarks[i]);
        vector<Person> persons(N+1);
        int uid,pid,score;
        for(int i = 0; i < M; i++){
            scanf("%d%d%d",&uid,&pid,&score);
            if(score <= persons[uid].scores[pid]) continue;
            int fullmark = fullmarks[pid];
            if(score >= fullmark && persons[uid].scores[pid] != fullmark) persons[uid].perfects++;
            //if(score < 0) score = 0;
            if(score > fullmark) score = fullmark;
            persons[uid].scores[pid] = score;
        }
        vector<Person> ps;
        for(int i = 1; i <= N; i++){
            persons[i].computeSum();
            persons[i].id = i;
            if(persons[i].passCompiler) ps.push_back(persons[i]);
        }
        sort(ps.begin(),ps.end());
        int rk = 0;
        int now_sum = -1;
        int now_cnt = 1;
        for(int i = 0; i < ps.size(); i++){
            int sum = ps[i].sum;
            if(sum != now_sum){
                rk += now_cnt;
                now_sum = sum;
                now_cnt = 1;
            }else{
                now_cnt++;
            }
            printf("%d %05d %d",rk,ps[i].id,sum);
            for(int j = 1; j <= K; j++){
                int score = ps[i].scores[j];
                if(score != -2){
                    if(score < 0) score = 0;
                    printf(" %d",score);
                }else{
                    printf(" -");
                }
            }
            cout << endl;
        }
        return 0;
    }
    

  • 相关阅读:
    解决Oracle XE报错ORA-12516(oracle回话数超出限制)
    端口被占用如何处理
    ORACLE initialization or shutdown in progress 错误解决办法
    oracle的闪回功能
    Linux入门
    oracle字段like多个条件
    navicat常用快捷键与SQL基本使用
    Oracle四舍五入,向上取整,向下取整
    无限循环小数化分数
    筛选素数
  • 原文地址:https://www.cnblogs.com/aiwz/p/6154072.html
Copyright © 2020-2023  润新知