1025 PAT Ranking (25 分| 排序,附详细注释,逻辑分析)

写在前面

  • 实现思路
    • 结构体数组封装学生元数据信息,也可用vector容器数组
    • 针对不同考场学生,局部排序local_rank、局部处理同分数问题
    • 学生整体排序,循环处理同分数问题并非降序final_rank打印学生信息
    • 另,下标初始值0。
      • 如非0开始涉及排序问题,逻辑处理变得繁琐
  • 题目不难,下标处理、排序函数耗费时间
    • 预计a题时间35分钟

测试用例

input:
2
5
1234567890001 95
1234567890005 100
1234567890003 95
1234567890002 77
1234567890004 85
4
1234567890013 65
1234567890011 25
1234567890014 100
1234567890012 85

output:
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

ac代码

  • 推荐
#include 
#include 
#include 
#include 

using namespace std;
struct Student
{
    char id[15];
    int score;
    int location_number;  // 考场号
    int local_rank;  // 考场内排名
} stu[30010];
bool cmp(Student a, Student b)
{
    if(a.score != b.score) return a.score > b.score;
    else return strcmp(a.id, b.id)<0;
}

int main()
{
    int n, k, num = 0;  // 总考生数num
    scanf("%d", &n);  // n为考场数
    for(int i=1; i<=n; i++)
    {
        scanf("%d", &k);  // 当前考场内人数
        for(int j=0; j<k; j++)
        {
            scanf("%s %d", stu[num].id, &stu[num].score);
            stu[num].location_number = i;  // 考场号为i
            num++;
        }

        sort(stu+num-k, stu + num, cmp);  // 将该考场的考生排序
        stu[num-k].local_rank = 1;
        for(int j=num-k+1; j <= num; j++)  // 剩余考生逻辑处理
        {
            if(stu[j].score == stu[j-1].score)  // 同分数情况
                stu[j].local_rank = stu[j-1].local_rank;
            else
                // local_rank 为该考生前的人数
                stu[j].local_rank = j - (num-k)+1;
        }
    }

    printf("%d\n", num);
    // 将所有考生排序
    sort(stu, stu+num, cmp);
    int r = 1;  // 当前考生排名
    for(int i=0; i<num; i++)
    {
        // 当前考生与上一个考生分数不同时,让r更新为人数+1
        if(stu[i].score != stu[i-1].score)
            r = i+1;
        printf("%s ", stu[i].id);
        printf("%d %d %d\n", r, stu[i].location_number, stu[i].local_rank);
    }
}

学习代码

  • 不推荐,下标处理逻辑更不容易理解
#include 
#include 
#include 
using namespace std;
struct student {
    long long int no;
    int score, finrank, loca, locarank;
};
bool cmp1(student a, student b) {
    return a.score != b.score ? a.score > b.score : a.no < b.no;
}
int main() {
    int n, m;
    scanf("%d", &n);
    vector<student> fin;
    for(int i = 1; i <= n; i++) {
        scanf("%d", &m);
        vector<student> v(m);
        for(int j = 0; j < m; j++) {
            scanf("%lld %d", &v[j].no, &v[j].score);
            v[j].loca = i;
        }
        sort(v.begin(), v.end(), cmp1);
        v[0].locarank = 1;
        fin.push_back(v[0]);
        for(int j = 1; j < m; j++) {
            v[j].locarank = (v[j].score == v[j - 1].score) ? (v[j - 1].locarank) : (j + 1);
            fin.push_back(v[j]);
        }
    }
    sort(fin.begin(), fin.end(), cmp1);
    fin[0].finrank = 1;
    for(int j = 1; j < fin.size(); j++)
        fin[j].finrank = (fin[j].score == fin[j - 1].score) ? (fin[j - 1].finrank) : (j + 1);
    printf("%d\n", fin.size());
    for(int i = 0; i < fin.size(); i++)
        printf("%013lld %d %d %d\n", fin[i].no, fin[i].finrank, fin[i].loca, fin[i].locarank);
    return 0;
}

知识点小结

// 数组局部排序
sort(stu+num-k, stu + num, cmp);  // 将该考场的考生排序

// 长整型数据定义、读入、输出
long long int no;
scanf("%lld %d", &v[j].no, &v[j].score);
printf("%013lld %d %d %d\n", fin[i].no, fin[i].finrank, fin[i].loca, fin[i].locarank);

你可能感兴趣的:(PAT(甲级),算法比赛相关)