PTA 7-41 PTA排名汇总(多阶段排序应用)

本题考点:

  • 多个阶段排序的组合

计算机程序设计能力考试(Programming Ability Test,简称PAT)旨在通过统一组织的在线考试及自动评测方法客观地评判考生的算法设计与程序设计实现能力,科学的评价计算机程序设计人才,为企业选拔人才提供参考标准(网址http://www.patest.cn)。
每次考试会在若干个不同的考点同时举行,每个考点用局域网,产生本考点的成绩。考试结束后,各个考点的成绩将即刻汇总成一张总的排名表。
现在就请你写一个程序自动归并各个考点的成绩并生成总排名表。
输入格式:
输入的第一行给出一个正整数N(≤100),代表考点总数。随后给出N个考点的成绩,格式为:首先一行给出正整数K(≤300),代表该考点的考生总数;随后K行,每行给出1个考生的信息,包括考号(由13位整数字组成)和得分(为[0,100]区间内的整数),中间用空格分隔。
输出格式:
首先在第一行里输出考生总数。随后输出汇总的排名表,每个考生的信息占一行,顺序为:考号、最终排名、考点编号、在该考点的排名。其中考点按输入给出的顺序从1到N编号。考生的输出须按最终排名的非递减顺序输出,获得相同分数的考生应有相同名次,并按考号的递增顺序输出。
输入样例:
2
5
1234567890001 95
1234567890005 100
1234567890003 95
1234567890002 77
1234567890004 85
4
1234567890013 65
1234567890011 25
1234567890014 100
1234567890012 85
输出样例:
9
1234567890005 1 1 1
1234567890014 1 2 1
1234567890001 3 1 2
1234567890003 3 1 2
1234567890004 5 1 4
1234567890012 5 2 2
1234567890002 7 1 5
1234567890013 8 2 3
1234567890011 9 2 4

这道题乍一看好像是归并排序,但是并不能简单的使用归并排序,因为可能涉及到多于两个数组的归并。

所以我们可以将所有的人的乘积保存到一个一维数组中,然后分段来排序每个考场的成绩,并且在这个段内进行排名。

最后再将所有的人的成绩一起排名计数即可。

完整代码如下:

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;

#define MAXN 105
#define MAXK 305

int N, K;
int persons[MAXN];  // 记录每个考点的人数

struct Person {
    char id[15];    // 十三位的考号
    int score, testCenter;      // 分数,考点
    int rankCenter, rankAll;    // 考点的排名,总排名
}stu[MAXN * MAXK];  // 记录每个人的信息

// 根据分数排名
bool cmp(Person a, Person b)
{
    if(a.score == b.score)
        return strcmp(a.id, b.id) < 0;
    else
        return a.score > b.score;
}

int main()
{
    freopen("data.txt", "r", stdin);
    scanf("%d", &N);    // 总考点数目
    int sum = 0, lastPos = 0;   // 上一个排名的最后一个位置
    int level = 1;  // 排名
    for (int i = 1; i <= N; i++)
    {
        scanf("%d", &K);    // 该考点的总人数
        for (int j = 1; j <= K; j++)
        {   // 读取学号和分数
            scanf("%s%d", &stu[sum + j].id, &stu[sum + j].score);
            stu[sum + j].testCenter = i;    // 当前学生的考场号
        }
        sum += K;  // 当前总人数
        sort(stu + lastPos + 1, stu + sum + 1, cmp);    // 当前考场排序
        level = 1;
        for (int i = lastPos + 1; i <= sum; i++)
        {
            if(i == lastPos + 1)
            {
                stu[i].rankCenter = level;
            }else 
            {
                if(stu[i].score == stu[i-1].score)
                    stu[i].rankCenter = stu[i - 1].rankCenter;
                else
                    stu[i].rankCenter = level;
            }
            level++;
        }
        lastPos = sum;  // 记录上一个排序的位置的最后一个
    }
    sort(stu + 1, stu + sum + 1, cmp);
    level = 1;
    for (int i = 1; i <= sum; i++)
    {
        if(i == 1)
        {
            stu[i].rankAll = level;
        }else
        {
            if(stu[i].score == stu[i-1].score)
                stu[i].rankAll = stu[i - 1].rankAll;
            else
                stu[i].rankAll = level;
        }
        level++;
    }
    printf("%d\n", sum);
    for (int i = 1; i <= sum; i++)
    {
        printf("%s %d %d %d\n", stu[i].id, stu[i].rankAll, stu[i].testCenter, stu[i].rankCenter);
    }

    return 0;
}
posted @ 2020-04-11 10:35  南风sa  阅读(108)  评论(0编辑  收藏