1095 解码PAT准考证 (25分) PAT乙级真题

1095 解码PAT准考证 (25分)

PAT 准考证号由 4 部分组成:
·第 1 位是级别,即 T 代表顶级;A 代表甲级;B 代表乙级;
·第 2~4 位是考场编号,范围从 101 到 999;
·第 5~10 位是考试日期,格式为年、月、日顺次各占 2 位;
·最后 11~13 位是考生编号,范围从 000 到 999。
现给定一系列考生的准考证号和他们的成绩,请你按照要求输出各种统计信息。

输入格式:
输 入 首 先 在 一 行 中 给 出 两 个 正 整 数 N ( ≤ 1 0 ​ 4 ​ ​ ) 输入首先在一行中给出两个正整数 N(≤10^{​4}​​ ) N104和 M(≤100),分别为考生人数和统计要求的个数。
接下来 N 行,每行给出一个考生的准考证号和其分数(在区间 [0,100] 内的整数),其间以空格分隔。
考生信息之后,再给出 M 行,每行给出一个统计要求,格式为:类型 指令,其中
·类型 为 1 表示要求按分数非升序输出某个指定级别的考生的成绩,对应的 指令 则给出代表指定级别的字母;
·类型 为 2 表示要求将某指定考场的考生人数和总分统计输出,对应的 指令 则给出指定考场的编号;
·类型 为 3 表示要求将某指定日期的考生人数分考场统计输出,对应的 指令 则给出指定日期,格式与准考证上日期相同。

输出格式:
对每项统计要求,首先在一行中输出 Case #: 要求,其中 # 是该项要求的编号,从 1 开始;要求 即复制输入给出的要求。随后输出相应的统计结果:
·类型 为 1 的指令,输出格式与输入的考生信息格式相同,即 准考证号 成绩。对于分数并列的考生,按其准考证号的字典序递增输出(题目保证无重复准考证号);
·类型 为 2 的指令,按 人数 总分 的格式输出;
·类型 为 3 的指令,输出按人数非递增顺序,格式为 考场编号 总人数。若人数并列则按考场编号递增顺序输出。
如果查询结果为空,则输出 NA。

输入样例:

8 4
B123180908127 99
B102180908003 86
A112180318002 98
T107150310127 62
A107180908108 100
T123180908010 78
B112160918035 88
A107180908021 98
1 A
2 107
3 180908
2 999

输出样例:

Case 1: 1 A
A107180908108 100
A107180908021 98
A112180318002 98
Case 2: 2 107
3 260
Case 3: 3 180908
107 2
123 2
102 1
Case 4: 2 999
NA

这道题给我的感觉是遇到了一个“甲方”,提出的条件还挺多。我是用一个包含了各项信息的结构体来存储每个考生的信息的,然后将数据一分为三,分别针对三种case进行排序,然后按需查找。这样可以最大程度的降低每次查找还要排序的开销。case 3 比前两个要麻烦一点,在给出每次查找条件后要对每个考场的人数进行统计。我一开始为了逻辑统一,把考场编号从1开始,然而我用快排的时候是从0开始的,于是悲剧了,而且这个bug我用了好几个测试数据才测出来问题所在。这道题我在写完以后去看了一些做法,柳神写的cmp真的惊艳到我了,赶紧拿小本本出来学习。
虽然代码满分过了,时间也还过得去,但是现在发现还有不少改进的地方:case 2和case3其实没有必要排序的,被case 1带的惯性思维了,排序后的查找其实快不了多少,然而排序的时间确是实实在在的消耗了。下面我给的是便于阅读输出结果的使用文件输入输出代码,不用文件形式看结果会有点不好阅读。使用的时候在同目录下创建一个"1095.in"作为输入,会有一个“1095.out”作为输出文件,文本文档形式打开就好了。下面是代码:

#include<stdio.h>
#include<stdlib.h>

typedef struct Stu
{
    char level;
    int exam_number;
    long date;
    int id_number;
    int grade;
}Stu;

typedef struct Room
{
    int Room_no;
    int count;
}Room;

int cmp1(const void *a,const void *b);
int cmp2(const void *a,const void *b);
int cmp3(const void *a,const void *b);
int cmp4(const void *a,const void *b);
void case_1(char c,struct Stu student[4][10000],int n,FILE *q);
void case_2(struct Stu student[4][10000],int n,int exam,FILE *q);
void case_3(struct Stu student[4][10000],int n,long date,FILE *q);

int main(void)
{
    FILE *p = fopen("./1095.in", "r");
    FILE *q = fopen("./1095.out", "w");
    Stu student[4][10000];
    int n,m;
    int i,j;
    long temp,temp1,temp2;
    char c;
    fscanf(p,"%d %d%c",&n,&m,&c);
    for(i = 0;i < n;i++)
    {
        fscanf(p,"%c",&c);                     //level
        for(j = 1;j <= 3;j++)
        {
            student[j][i].level = c;
            student[j][i].date = 0;
            student[j][i].exam_number = 0;
            student[j][i].grade = 0;
            student[j][i].id_number = 0;
        }
        temp = 0;
        for(j = 1;j <= 3;j++)           //exam_number
        {
            fscanf(p,"%c",&c);
            temp = temp * 10 + (c - '0');
        }
        temp1 = 0;
        for(j = 1;j <= 6;j++)               //date
        {
            fscanf(p,"%c",&c);
            temp1 = temp1 * 10 + (c - '0');
        }
        temp2 = 0;
        for(j = 1;j <= 3;j++)           //id_number
        {
            fscanf(p,"%c",&c);
            temp2 = temp2 * 10 + (c - '0');
            student[j][i].date = temp1;
            student[j][i].exam_number = temp;
        }
        fscanf(p,"%ld%c",&temp,&c);
        for(j = 1;j <= 3;j++)
        {
            student[j][i].grade = temp;
            student[j][i].id_number = temp2;
        }
    }
    qsort(&student[1][0],n,sizeof(Stu),cmp1);
    qsort(&student[2][0],n,sizeof(Stu),cmp2);
    qsort(&student[3][0],n,sizeof(Stu),cmp3);
    for(i = 1;i <= m;i++)
    {
        fprintf(q,"Case %d: ",i);
        fscanf(p,"%ld",&temp);
        if(temp == 1)
        {
            fscanf(p,"%c",&c);
            fscanf(p,"%c",&c);
            fprintf(q,"1 %c\n",c);
            case_1(c,student,n,q);
        }
        else
        {
            if(temp == 2)
            {
                fscanf(p,"%ld",&temp);
                fprintf(q,"2 %ld\n",temp);
                case_2(student,n,temp,q);
            }
            else
            {
                fscanf(p,"%ld",&temp);
                fprintf(q,"3 %06ld\n",temp);
                case_3(student,n,temp,q);
            }
        }
        if(i < m) fprintf(q,"\n");
    }
    fclose(p);
    fclose(q);
    return 0;
}


int cmp1(const void *a,const void *b)
{
     struct Stu *aa=(Stu *)a;
     struct Stu *bb=(Stu *)b;
     int f = 1;
     if(aa->level > bb->level)
     {
         f = 1;
     }
     else
     {
         if (aa->level < bb->level)
         {
             f = -1;
         }
         else                       //级别相同
         {
             if(aa -> grade < bb -> grade)
             {
                 f = 1;
             }
             else
             {
                 if(aa -> grade > bb -> grade)
                 {
                     f = -1;
                 }
                 else               //成绩相等
                 {
                     if(aa -> exam_number > bb ->exam_number)
                     {
                         f = 1;
                     }
                     else
                     {
                         if(aa -> exam_number < bb ->exam_number)
                         {
                             f = -1;
                         }
                         else       //同一考场
                         {
                             if(aa -> date > bb ->date)
                             {
                                 f = 1;
                             }
                             else
                             {
                                 if(aa -> date < bb ->date)
                                 {
                                     f = -1;
                                 }
                                 else       //同一天
                                 {
                                     if(aa -> id_number > bb ->id_number)
                                     {
                                         f = 1;
                                     }
                                     else f = -1;
                                 }
                             }
                         }
                     }
                 }
             }
         }
     }
     return f;
}

int cmp2(const void *a,const void *b)
{
    struct Stu *aa=(Stu *)a;
    struct Stu *bb=(Stu *)b;
    int f = 0;
    if(aa -> exam_number > bb -> exam_number) f = 1;
    else f = -1;
    return f;
}

int cmp3(const void *a,const void *b)
{
    struct Stu *aa=(Stu *)a;
    struct Stu *bb=(Stu *)b;
    int f = 0;
    if(aa -> date > bb ->date)
    {
        f = 1;
    }
    else
    {
        if(aa -> date < bb ->date)
        {
            f = -1;
        }
        else
        {
            if(aa -> exam_number > bb -> exam_number) f = 1;
            else f = -1;
        }
    }
    return f;
}

void case_1(char c,struct Stu student[4][10000],int n,FILE *q)
{
    int i = 0;
    int f = 1;
    while(student[1][i].level != c && i < n)
    {
        i++;
    }
    while(student[1][i].level == c && i < n)
    {
        fprintf(q,"%c%03d%06ld%03d %d",student[1][i].level,student[1][i].exam_number,student[1][i].date,student[1][i].id_number,student[1][i].grade);
        i++;
        f = 0;
        if(student[1][i].level == c && i < n) fprintf(q,"\n");
    }
    if (f) fprintf(q,"NA");
}

void case_2(struct Stu student[4][10000],int n,int exam,FILE *q)
{
    int s = 0,i = 0;
    int sum = 0;
    while(student[2][i].exam_number != exam && i < n)
    {
        i++;
    }
    while(student[2][i].exam_number == exam && i < n)
    {
        s++;
        sum += student[2][i].grade;
        i++;
    }
    if(s != 0) fprintf(q,"%d %ld",s,sum);
    else fprintf(q,"NA");
}

void case_3(struct Stu student[4][10000],int n,long date,FILE *q)
{
    Room a[1000];
    int i;
    int f = 1;
    for(i = 0;i < 1000;i++)
    {
        a[i].Room_no = i;
        a[i].count = 0;
    }
    for(i = 0;i < n;i++)
    {
        if(student[3][i].date == date)
        {
            a[student[3][i].exam_number].count++;
        }
    }
    qsort(a,1000,sizeof(Room),cmp4);
    i = 0;
    while(a[i].count != 0)
    {
        fprintf(q,"%d %d",a[i].Room_no,a[i].count);
        i++;
        if(a[i].count != 0)fprintf(q,"\n");
        f = 0;
    }
    if (f) fprintf(q,"NA");
}

int cmp4(const void *a,const void *b)
{
    struct Room *aa=(Room *)a;
    struct Room *bb=(Room *)b;
    int f = 0;
    if(aa -> count < bb -> count)
    {
        f = 1;
    }
    else
    {
        if(aa -> count > bb -> count)
        {
            f = -1;
        }
        else
        {
            if(aa -> Room_no > bb -> Room_no) f = 1;
            else f = -1;
        }
    }
    return f;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值