【PAT】1025 PAT Ranking (25 分)

46 篇文章 0 订阅
44 篇文章 0 订阅
  • 题目大意:每个测试都允许在不同地方同时运行。为PAT写一个可以融合所有排名列表并且生成最终排名的程序。

    输出按最终排名增序排。成绩相同的考生排名相同(比如有两个并列第一名,则没有第二名,直接跳到第三名),然后按注册账号增序排序。

  • 思路:

    1. 用结构体存考生信息,里面包含考生号、成绩、考区号、考区排名(输入完该区信息后排名)
    2. 用二维数组存各个考区的考生信息,每存完一个考区就进行排序,然后分配考区排名,并将该考生放入大数组里
    3. 最后再给大数组排序、分配排名,然后输出信息
  • 知识点:

    1. struct
    2. 二维数组
    3. sort
    4. strcmp()
  • 代码:

    #include <iostream>
    #include <vector>
    #include <string.h>
    #include <algorithm>
    using namespace std;
    
    struct testee{
        char id[14];    // 用long long int需要在输入输出时用%lld格式
        int lid, grade = 0, lrank = -1, trank = -1;
    };
    
    bool cmp(testee a, testee b){
        return a.grade != b.grade ? a.grade > b.grade : strcmp(a.id, b.id) < 0;
    }
    
    int main()
    {
        int n, i, j;
        scanf("%d", &n);
        vector<vector<testee>> v;
        vector<testee> merged;
        for(i = 0; i < n; i++){
            int k;
            scanf("%d", &k);
            vector<testee> temp(k);
            for(j = 0; j < k; j++){
                temp[j].lid = i + 1;
                scanf("%s %d", temp[j].id, &temp[j].grade);
            }
            sort(temp.begin(), temp.end(), cmp);
            // ranking
            int rank = 1;
            for(j = 0; j < k; j++){
                if(j == 0)
                    temp[j].lrank = rank++;
                else{
                    if(temp[j].grade == temp[j - 1].grade){
                        temp[j].lrank = temp[j - 1].lrank;
                        rank++; // 注意排名还得加1
                    }
                    else
                        temp[j].lrank = rank++;
                }
            }
            v.push_back(temp);
        }
        for(i = 0; i < n; i++){
            for(auto l = v[i].begin(); l != v[i].end(); l++)
                merged.push_back(*l);
        }
        sort(merged.begin(), merged.end(), cmp);
        // ranking
        int rank = 1;
        for(i = 0; i < merged.size(); i++){
            if(i == 0)
                merged[i].trank = rank++;
            else{
                if(merged[i].grade == merged[i - 1].grade){
                    merged[i].trank = merged[i - 1].trank;
                    rank++;
                }
                else
                    merged[i].trank = rank++;
            }
        }
    
        printf("%d\n", merged.size());  // 注意格式
        for(i = 0; i < merged.size(); i++)
            printf("%s %d %d %d\n", merged[i].id, merged[i].trank, merged[i].lid, merged[i].lrank);
        return 0;
    }
    
  • 总结:

    1. 细节:

      1. 排序时要注意:如有两个并列第一名,则没有第二名,直接跳到第三名。

        实现方法很简单:在将前一位考生的排名赋值给当前考生的排名后,再将排名加一即可。

      2. 考生id为13位,int型变量最多可表示2147483647~-2147483647以内的数,所以应该用字符串数组或者long long int型变量存储。注意:用long long int需要在输入输出时用%lld格式

        • int,long,long long类型的数值范围(转自qianbitou000):

          • int: 4byte = 32 bit,有符号signed范围:2^31-1 ~ -2^31,即:2147483647 ~ -2147483648;无符号unsigned范围:2^32-1 ~ 0,即:4294967295 ~ 0

          • long int: 4 byte = 32 bit (同int型

          • long long int:9223372036854775807(>10^18)~-9223372036854775808

          • double: 8 byte = 64 bit,范围:1.79769e+308 ~ 2.22507e-308

          • long double: 12 byte = 96 bit ,范围: 1.18973e+4932 ~ 3.3621e-4932

          • float: 4 byte= 32 bit ,范围: 3.40282e+038 ~ 1.17549e-038

    2. 输出时注意要加回车符号。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值