PAT 乙级 1095 解码PAT准考证
1. 题目简述及在线测试位置
1.1 已知考生准考证号和成绩,统计如下内容:(1)由高向低输出指定级别的考生成绩(2)统计指定考点的考生人数和总得分 (3)统计指定日期的考点和其对应的考生人数
1.2 在线测试位置: 1095 解码PAT准考证
2. 基本思路
2.1 使用结构体数组存储考生信息:通过分离准考证号(字符串)可以得到 考试等级、考试地点、考试时间
#define MAX 10000
struct Student
{
string ID; //准考证号
int Score; //得分
char Grade; //考试等级
int ExamRoom; //考试地点
int Date; //考试日期
};
struct Student Stu[MAX];
2.2 对于 从高到低输出指定级别的考生成绩:对结构体数组,第一优先级按成绩排序、第二优先级按准考证号字典序排序,然后遍历数组,打印指定级别的考生信息
bool Compare(struct Student a, struct Student b)
{
if (a.Score != b.Score)
return a.Score > b.Score;
else
return a.ID < b.ID;
}
2.3 对于 统计指定考点的总得分:遍历结构体数组的考点信息元素,通过判定语句识别指定的考点并统计相关信息即可
2.4 对于 统计指定日期的考点和其对应的考生人数 :遍历结构体数组的考试时间元素,通过判定语句识别指定日期,将统计信息存储到另一个结构体数组RoomPeople中
之后排序,第一排序优先级是考试人数、第二优先级是考点的字典序,随后打印
struct Record
{
int Room;
int PeopleNum;
};
struct Record RoomPeople[1000];
bool CompareRecord(struct Record a, struct Record b)
{
if (a.PeopleNum != b.PeopleNum)
return a.PeopleNum > b.PeopleNum;
else
return a.Room < b.Room;
}
2.5 注意:当输出考试日期时,必须是6位字符串,因此不能使用整型直接存储日期信息。另外,cin cout的效率远比 scanf printf低得多,会触发测试点超时
3. 完整AC代码
#include <algorithm>
#include <string>
#include <iostream>
using namespace std;
#define MAX 10000
struct Student
{
string ID;
int Score;
char Grade;
int ExamRoom;
int Date;
};
struct Record
{
int Room;
int PeopleNum;
};
bool CompareRecord(struct Record a, struct Record b)
{
if (a.PeopleNum != b.PeopleNum)
return a.PeopleNum > b.PeopleNum;
else
return a.Room < b.Room;
}
bool Compare(struct Student a, struct Student b)
{
if (a.Score != b.Score)
return a.Score > b.Score;
else
return a.ID < b.ID;
}
void Separate(struct Student S[], int Index, string ID);
int main()
{
int RecordNum, QuestionNum,Instrument;
scanf("%d %d", &RecordNum, &QuestionNum);
struct Student Stu[MAX];
char ID[13]; int Score;
for (int i = 0; i < RecordNum; i++)
{
scanf("%s %d", &ID, &Score);
ID[13] = '\0';
Stu[i].ID = ID;
Stu[i].Score = Score;
Separate(Stu, i, ID);
}
bool ResultFlag; //用于标示是否存在符合查询条件的结果,默认不存在
for(int Case=1; Case<= QuestionNum; Case++)
{
ResultFlag = false;
scanf("%d ", &Instrument);
if (Instrument == 1)
{
sort(Stu, Stu + RecordNum, Compare);
char Grade;
scanf("%c", &Grade);
printf("Case %d: %d %c\n", Case, Instrument, Grade);
for (int i = 0; i < RecordNum; i++)
{
if (Stu[i].Grade == Grade)
{
printf("%s %d\n", Stu[i].ID.c_str(), Stu[i].Score);
ResultFlag = true;
}
}
if (!ResultFlag)
printf("NA\n");
}
else if (Instrument == 2)
{
int ExamRoom, StuNum = 0, Sum = 0;
scanf("%d", &ExamRoom);
printf("Case %d: %d %d\n", Case, Instrument, ExamRoom);
for (int i = 0; i < RecordNum; i++)
{
if (Stu[i].ExamRoom == ExamRoom)
{
ResultFlag = true;
StuNum++;
Sum += Stu[i].Score;
}
}
if (ResultFlag)
printf("%d %d\n", StuNum,Sum);
else
printf("NA\n");
}
else if (Instrument == 3)
{
int Date; char StrDate[7];
scanf("%s",StrDate);
StrDate[6] = '\0';
Date = stoi(StrDate);
//注意日期的输出格式:必须是六位 010101,所以通过字符的形式输出
printf("Case %d: %d %s\n", Case, Instrument, StrDate);
struct Record RoomPeople[1000];
for (int i = 0; i < 1000; i++)
{
RoomPeople[i].PeopleNum = 0;
RoomPeople[i].Room = i;
}
for (int i = 0; i < RecordNum; i++)
{
if (Stu[i].Date == Date)
{
RoomPeople[Stu[i].ExamRoom].PeopleNum++;
ResultFlag = true;
}
}
if (ResultFlag)
{
sort(RoomPeople, RoomPeople + 1000, CompareRecord);
for (int i = 0; i < 1000; i++)
{
if (!RoomPeople[i].PeopleNum)
break;
else
printf("%d %d\n", RoomPeople[i].Room, RoomPeople[i].PeopleNum);
}
}
else
printf("NA\n");
}
}
return 0;
}
void Separate(struct Student S[], int Index, string ID)
{
S[Index].Grade = ID[0]; //0 mean Grade
char ExamRoom[4]; int Count = 0;
for (int i = 1; i <= 3; i++) //1-3 mean ExamRoom
ExamRoom[Count++] = ID[i];
ExamRoom[Count] = '\0';
S[Index].ExamRoom = stoi(ExamRoom);
char Date[7]; Count = 0;
for (int i = 4; i <= 9; i++)//4-9 mean Exam's Date
Date[Count++] = ID[i];
Date[Count] = '\0';
S[Index].Date = stoi(Date);
return;
}