1. 程式人生 > >PTA 10-排序5 PAT Judge(25 分)

PTA 10-排序5 PAT Judge(25 分)

10-排序5 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.

  • 輸入格式
    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 submissions. 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 submission in the following format:
    user_id problem_id partial_score_obtained
    where partial_score_obtained is either −1 if the submission 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.

  • 輸出格式
    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.

解題方法:
這道題目從解決上來說難度不大,我這裡是建立一個儲存學生資訊的結構體,然後按照題目要求進行排序即可。


易錯點:
1. 學生ID是從1開始的,所以在開陣列的時候要為N+1
2. 不展示的在排行榜上的是那些沒有一題編譯通過或者一題都沒交的,但是如果交了是0,還是需要體現在排行榜上的。
3. 排名在計算時,如果跟前面成績相同,排名就為前面的同學,如果不同,不能簡單以前面同學加一作為輸出。


程式:

#include <stdio.h>
#include <vector>
#include <algorithm>
using namespace std;

struct Student
{
    int ID, Score, PerfectSolveNum, Rank, isSubmit;
    int Problem[6]; /* 下標從1開始 */
};

int cmp(Student s1, Student s2)
{   /* 比較函式 */
    if (s1.Score != s2.Score)   /* 如果分數不相同,按分數降序輸出 */
        return s1.Score > s2.Score;
    else    /* 如果完美解題數相同,按ID升序輸出,否則按完美解題數降序輸出 */
        return s1.PerfectSolveNum == s2.PerfectSolveNum ? s1.ID < s2.ID : s1.PerfectSolveNum > s2.PerfectSolveNum;
}

void PrintfInfo(Student s, int K)
{   /* 列印學生每道題的分數 */
    for (int i = 1; i <= K; i++)
        if (s.Problem[i] == -2)
            printf(" -");
        else
            printf(" %d", s.Problem[i]);
    printf("\n");
}

int main(int argc, char const *argv[])
{
    int N, K, M, Problem[6];
    scanf("%d %d %d", &N, &K, &M);
    Student Stu[N+1];
    for (int i = 1; i <= N; i++)
    {   /* 初始化結構體陣列 */
        Stu[i].isSubmit = 0;
        Stu[i].Score = 0;
        Stu[i].PerfectSolveNum = 0;
        Stu[i].Rank = 0;
        for (int j = 1; j <= K; j++)
            Stu[i].Problem[j] = -2; /* 方便後面確認是否有提交 */
    }
    for (int i = 1; i <= K; i++)
        scanf("%d", &Problem[i]);
    for (int i = 0; i < M; i++)
    {   /* 計算學生成績 */
        int ID, ProblemID, Grade;
        scanf("%d %d %d", &ID, &ProblemID, &Grade);
        Stu[ID].ID = ID;    /* 傳入ID資訊 */
        if (Grade > Stu[ID].Problem[ProblemID]) /* 如果再次提交分數更高 */
        {
            if (Grade == -1)    /* 如果未提交過且編譯錯誤 */   
                Stu[ID].Problem[ProblemID] = 0;
            else
            {
                Stu[ID].isSubmit = 1;
                Stu[ID].Problem[ProblemID] = Grade;
            }
            if (Grade == Problem[ProblemID])    /* 如果此次分數為滿分 */
                Stu[ID].PerfectSolveNum++;
        }       
    }
    vector <Student> v; /* 存放題目至少做一題的學生資訊 */
    for (int i = 1; i <= N; i++)
    {
        int flag = 0;   /* 標誌是否全做 */
        for (int j = 1; j <= K; j++)
        {
            if (Stu[i].Problem[j] == -2)
                continue;
            else
            {
                flag = 1;
                Stu[i].Score += Stu[i].Problem[j];
            }           
        }
        if (flag == 1 && Stu[i].isSubmit == 1)  /* 如果至少有一題編譯通過就放入向量 */
            v.push_back(Stu[i]);
    }
    sort(v.begin(), v.end(), cmp);
    v[0].Rank = 1;
    printf("%d %05d %d",v[0].Rank, v[0].ID, v[0].Score);
    PrintfInfo(v[0], K);
    for (int i = 1; i < v.size(); i++)
    {
        if (v[i].Score == v[i-1].Score)
            v[i].Rank = v[i-1].Rank;
        else
            v[i].Rank = i + 1;
        printf("%d %05d %d", v[i].Rank, v[i].ID, v[i].Score);
        PrintfInfo(v[i], K);
    }
    return 0;
}

如果對您有幫助,幫忙點個小拇指唄~