题目
链接:PAT (Basic Level) Practice 1095 解码PAT准考证
PAT 准考证号由 4 部分组成:
- 第 1 位是级别,即
T
代表顶级;A
代表甲级;B
代表乙级;- 第 2~4 位是考场编号,范围从 101 到 999;
- 第 5~10 位是考试日期,格式为年、月、日顺次各占 2 位;
- 最后 11~13 位是考生编号,范围从 000 到 999。
现给定一系列考生的准考证号和他们的成绩,请你按照要求输出各种统计信息。
输入格式:
输入首先在一行中给出两个正整数和 ,分别为考生人数和统计要求的个数。
接下来 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
思路
这道题磨了一个多星期还是没解决,现在还只能过一个点15分,3个点超时(用了三个for循环嵌套,不超时才怪)。
先留着过些日子再改吧,欢迎讨论。
- 类型1的要求涉及成绩和级别(准考证号);
- 类型2的要求涉及考场编号和考场人数和成绩;
- 类型3的要求涉及日期和考场考生人数。
所以用两个结构体数组分别存入考生和考场信息,考生信息包括准考证号、和成绩,考场信息包括考场编号和考场人数;考场编号用考场结构体数组下标表示。
代码
#include<stdio.h>
#include<string.h>
typedef struct student{
int grade;
char Tnumb[14];
}Student;
typedef struct eroom{
int Pamou;
int Tgrade;
}Eroom;
int main()
{
int N, M;
scanf("%d %d", &N, &M);
Student S[N];
Eroom E[1000];
for(int i = 101; i < 1000; i++){ //结构体初始化
E[i].Pamou = 0;
E[i].Tgrade = 0;
}
for(int i = 0; i < N; i++){
char str[14];
int gra, En;
scanf("%s %d", str, &gra);
strcpy(S[i].Tnumb, str);
S[i].grade = gra;
En = (S[i].Tnumb[1] - '0') * 100 + (S[i].Tnumb[2] - '0') * 10 + (S[i].Tnumb[3] - '0');
E[En].Pamou += 1;
E[En].Tgrade += gra;
}
for(int i = 0; i < M; i++){
int type = 0, flag = 0;
scanf("%d", &type);
if(type == 1){ //类型1
char level;
Student S2[N];
int cnt = 0;
scanf(" %c", &level);
for(int j = 0; j < N; j++){
if(S[j].Tnumb[0] == level){
strcpy(S2[cnt].Tnumb, S[j].Tnumb); //得到符合条件的学生数据
S2[cnt].grade = S[j].grade;
cnt++;
flag = 1;
}
}
Student temp;
for(int p = 0; p < cnt; p++){ //排序
for(int q = p; q < cnt; q++){
if((S2[p].grade < S2[q].grade)||(S2[p].grade == S2[q].grade && S2[p].Tnumb < S2[q].Tnumb)){
//temp = S2[p];
strcpy(temp.Tnumb, S2[p].Tnumb);
temp.grade = S2[p].grade;
//S2[p] = S2[q];
strcpy(S2[p].Tnumb, S2[q].Tnumb);
S2[p].grade = S2[q].grade;
//S2[q] = temp;
strcpy(S2[q].Tnumb, temp.Tnumb);
S2[q].grade = temp.grade;
}
}
}
printf("Case %d: %d %c\n", i+1, type, level);
if(flag == 0){
printf("NA\n");
}
else{
for(int k = 0; k < cnt; k++){
printf("%s %d\n", S2[k].Tnumb, S2[k].grade);
}
}
}
else if(type == 2){ //类型2
int Enumb;
scanf("%d", &Enumb);
printf("Case %d: %d %03d\n", i+1, type, Enumb);
if(E[Enumb].Pamou == 0){
printf("NA\n");
}
else{
printf("%d %d\n", E[Enumb].Pamou, E[Enumb].Tgrade);
}
}
else if(type == 3){ //类型3
int data;
scanf("%d", &data);
Eroom E2[1000];
for(int j = 101; j < 1000; j++){ //结构体初始化
E2[j].Pamou = 0;
E2[j].Tgrade = 0;
}
int dat2,cnt2 = 0,en, flag3 = 0;
for(int j = 0; j < N; j++){
dat2 = (S[j].Tnumb[4] - '0') * 100000 + (S[j].Tnumb[5] - '0') * 10000 + (S[j].Tnumb[6] - '0')* 1000 + (S[j].Tnumb[7] - '0') * 100+ (S[j].Tnumb[8] - '0') * 10 + (S[j].Tnumb[9] - '0');
if(data == dat2){
en = (S[j].Tnumb[1] - '0') * 100 + (S[j].Tnumb[2] - '0') * 10 + (S[j].Tnumb[3] - '0');
E2[en].Pamou++;
flag3 = 1; //flag用来表示查询是否为空
}
}
printf("Case %d: %d %d\n", i+1, type, data);
if(flag3 == 0){
printf("NA\n");
}
else{
for(int k = N; k > 0; k--){
for(int j = 101; j < 1000; j++){
if(E2[j].Pamou == k){
printf("%d %d\n", j, k);
}
}
}
}
}
}
return 0;
}
---END---
其它相关问题
PAT-B 1091 N-自守数(C语言)
PAT-B 1092 最好吃的月饼(C语言)
PAT-B 1093 字符串A+B(C语言)
PAT-B 1094 谷歌的招聘(C语言)