1 条题解

  • 0
    @ 2025-4-11 22:43:35

    题意分析

    给定(C)个团队的(N)次运行结果(包括团队编号、问题编号、提交时间和是否通过),根据特定的评分规则计算各团队解决问题的数量和总时间,然后按照解决问题数量、总时间以及团队编号的顺序对团队进行排名,最后输出排名后的团队编号列表。

    解题思路

    1.首先读取团队数量(C)和运行结果数量(N),初始化每个团队的相关信息(排名、总时间、解决问题数量)。

    2.读取每次运行结果的详细信息并存储。

    3.按照提交时间对所有运行结果进行排序。

    4.遍历排序后的运行结果,根据运行结果的通过情况更新每个团队的解决问题数量和总时间。

    5.按照评分规则对团队进行排名,优先比较解决问题数量,数量相同再比较总时间,若都相同则按团队编号排序。 输出排名后的团队编号。

    分析

    - 排序运行结果是为了确保按照提交时间的先后顺序处理,这样能正确计算每个问题的第一次被接受的时间以及未通过尝试的次数。
    
    - 在更新团队信息时,对于已解决的问题,要计算总时间(包括第一次接受时间和未通过尝试的惩罚时间),并标记该问题已解决;对于未通过的尝试,只增加未通过次数的记录。
    
    - 排名时按照规则进行比较和交换,实现团队的正确排序。
    

    实现步骤

    - 定义结构体`node`用于存储每个团队的总时间、解决问题数量和团队编号(初始排名),定义数组`table`用于记录每个团队对每个问题的未通过尝试次数,`p`数组用于标记每个团队的每个问题是否已解决。
    
    - 定义结构体`input`用于存储每次运行结果的详细信息。
    
    - 读取输入的\(C\)和\(N\),初始化团队信息。
    
    - 读取\(N\)次运行结果的详细信息并存储在`in`数组中。
    
    - 使用冒泡排序按提交时间对运行结果进行排序。
    
    - 遍历排序后的运行结果,更新团队的解决问题数量和总时间。
    
    - 使用冒泡排序按照评分规则对团队进行排名。
    
    - 输出排名后的团队编号。
    

    代码实现

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    int c, n;
    struct node {
        int time, problem, rank;
    };
    int table[1020][1020];
    int p[1020][1020];
    struct input{
        int ci, pi, ti, ri;
    };
    struct input in[1000];
    int main()
    {
        struct node a[1020];
        memset(table, 0, sizeof(table));
        memset(p, 0, sizeof(p));
    
        scanf("%d%d", &c, &n);
        for(int i = 1; i <= c; i++){
            a[i].rank = i;
            a[i].time = 0;
            a[i].problem = 0;
        }
    
        for(int i = 0; i < n; i++){
            scanf("%d%d%d%d", &in[i].ci, &in[i].pi, &in[i].ti, &in[i].ri);
        }
    
        for(int i = 0; i < n; i++){
            int flag = 1;
            for(int j = 0; j < n - i - 1; j++){
                if(in[j].ti > in[j + 1].ti){
                    struct input t = in[j];
                    in[j] = in[j + 1];
                    in[j + 1] = t;
                    flag = 0;
                }
            }
            if(flag) break;
        }
    
        for(int i = 0; i < n; i++){
            if(p[in[i].ci][in[i].pi]) continue;
            if(in[i].ri){
                a[in[i].ci].problem += 1;
                a[in[i].ci].time += in[i].ti + table[in[i].ci][in[i].pi] * 1200;
                p[in[i].ci][in[i].pi] = 1;
            }
            else {
                table[in[i].ci][in[i].pi] += 1;
            }
        }
    
        for(int i = 1; i <= c; i++){
            int flag = 1;
            for(int j = 1; j <= c - i; j++){
                if(a[j].problem < a[j + 1].problem ||
                   a[j].problem == a[j + 1].problem && a[j].time > a[j + 1].time
                   ){
                    struct node b = a[j];
                    a[j] = a[j + 1];
                    a[j + 1] = b;
                    flag = 0;
                }
            }
    
    //        for(int i = 1; i <= c; i++){
    //        printf("%d %d %d",a[i].rank,a[i].problem,a[i].time);
    //        if(i!=c)printf("***");
    //        else printf("\n");
    //    }
            if(flag) break;
        }
    
        for(int i = 1; i <= c; i++){
            printf("%d", a[i].rank);
            if(i != c) printf(" ");
            else printf("\n");
        }
        return 0;
    }
    

    代码说明

    - `table[i][j]`表示团队\(i\)对问题\(j\)的未通过尝试次数。
    
    - `p[i][j]`表示团队\(i\)是否已解决问题\(j\),\(1\)表示已解决,\(0\)表示未解决。
    
    - 对运行结果排序时,通过冒泡排序比较`in[j].ti`和`in[j + 1].ti`的大小来交换位置。
    
    - 更新团队信息时,根据`in[i].ri`判断运行结果是否通过,若通过则更新团队的解决问题数量和总时间,并标记问题已解决;若未通过则增加未通过尝试次数。
    
    - 对团队排名时,通过冒泡排序比较团队的解决问题数量和总时间,若都相同则按团队编号排序。最后输出排名后的团队编号。
    
    • 1

    信息

    ID
    1379
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    5
    已通过
    1
    上传者