whenever

  • Home

  • Tags21

  • Categories6

  • Archives122

  • About

PAT乙级1095 || 解码PAT准考证(详解,C/C++示例,测试点分析)

Posted on 2020-01-16 In PAT

解码PAT准考证

题目描述

PAT 准考证号由 4 部分组成:

  • 第 1 位是级别,即 T 代表顶级;A 代表甲级;B 代表乙级;
  • 第 2~4 位是考场编号,范围从 101 到 999;
  • 第 5~10 位是考试日期,格式为年、月、日顺次各占 2 位;
  • 最后 11~13 位是考生编号,范围从 000 到 999。

现给定一系列考生的准考证号和他们的成绩,请你按照要求输出各种统计信息。

输入格式

输入首先在一行中给出两个正整数 N(≤$10^4$)和 M(≤100),分别为考生人数和统计要求的个数。

接下来 N 行,每行给出一个考生的准考证号和其分数(在区间 [0,100] 内的整数),其间以空格分隔。

考生信息之后,再给出 M 行,每行给出一个统计要求,格式为:类型 指令,其中

  • 类型 为 1 表示要求按分数非升序输出某个指定级别的考生的成绩,对应的 指令 则给出代表指定级别的字母;
  • 类型 为 2 表示要求将某指定考场的考生人数和总分统计输出,对应的 指令 则给出指定考场的编号;
  • 类型 为 3 表示要求将某指定日期的考生人数分考场统计输出,对应的 指令 则给出指定日期,格式与准考证上日期相同。

输出格式

对每项统计要求,首先在一行中输出 Case #: 要求,其中 # 是该项要求的编号,从 1 开始;要求 即复制输入给出的要求。随后输出相应的统计结果:

  • 类型 为 1 的指令,输出格式与输入的考生信息格式相同,即 准考证号 成绩。对于分数并列的考生,按其准考证号的字典序递增输出(题目保证无重复准考证号);
  • 类型 为 2 的指令,按 人数 总分 的格式输出;
  • 类型 为 3 的指令,输出按人数非递增顺序,格式为 考场编号 总人数。若人数并列则按考场编号递增顺序输出。

如果查询结果为空,则输出 NA。

输入样例1

1
2
3
4
5
6
7
8
9
10
11
12
13
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

输出样例1

1
2
3
4
5
6
7
8
9
10
11
12
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

输入样例2

1
2
3
4
5
6
7
8
1 6
T101000101000 0
3 000101
2 101
1 T
1 A
1 B
3 180908

输出样例2

1
2
3
4
5
6
7
8
9
10
11
12
Case 1: 3 000101
101 1
Case 2: 2 101
1 0
Case 3: 1 T
T101000101000 0
Case 4: 1 A
NA
Case 5: 1 B
NA
Case 6: 3 180908
NA

问题解决

解题思想

题目内容比较长,处理起来也就相对复杂些。根据指令的要求,很容易看出不仅要对准考证号整体处理,而且还要对部分内容进行处理,所以,存储每个考生信息的结构体中要分开存储各个部分的信息(如级别,考场编号等)。

之后分开处理各类型的统计要求。当某类型的统计要求查询结果为空,则输出NA。

注意复制输出统计要求中的日期时,宽度为6位,如001010,应输出为001010,而不是1010,如果日期按整数处理,则需要考虑输出宽度的问题,若日期不是按整数处理(比如字符串),则不需要考虑输出格式问题了。

坑点提醒

超时问题

  1. 此题出现超时问题一般是由于使用了cin输入,cout输出。因此需要将它们都改成scanf输入,printf输出。

  2. 如果还有超时,则一般是处理类型3的统计要求时使用了map,因为map会按键自动排序,会造成超时,将用到map的地方改成用unordered_map一般能解决问题。

  3. 其它超时可能就是自己的算法有问题了。

代码示例(C/C++)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#include <iostream>
#include <cstdlib>
#include <vector>
#include <unordered_map> //用map测试点3会超时
#include <algorithm>

using namespace std;

struct student {
string id, r, a, d, num; //分别为准考证号,级别,考场编号,考试日期,考生编号
int g; // 分数
};

struct room_num {
string a;
int c;
};

vector <student> stu;

bool cmp1(student x, student y) {
if (x.g != y.g) {
return x.g > y.g;
}
else {
return x.id < y.id;
}
}
bool cmp2(room_num x, room_num y) {
if (x.c != y.c) {
return x.c > y.c;
}
else {
return x.a < y.a;
}
}

void command1(string tmp, int &flag) {
sort(stu.begin(), stu.end(), cmp1);
for (int i = 0; i < stu.size(); i ++) {
if (stu[i].r == tmp) {
flag = 1;
printf("%s %d\n", stu[i].id.c_str(), stu[i].g);
}
}
}
void command2(string tmp, int &flag) {
int c = 0, sum = 0;
for (int i = 0; i < stu.size(); i ++) {
if (stu[i].a == tmp) {
flag = 1;
c++;
sum += stu[i].g;
}
}
if (flag) {
printf("%d %d\n", c, sum);
}
}
void command3(string tmp, int &flag) {
unordered_map <string, int> mp;
for (int i = 0; i < stu.size(); i ++) {
if (stu[i].d == tmp) {
flag = 1;
mp[stu[i].a]++;
}
}
vector <room_num> rn;
for (unordered_map <string, int> :: iterator it = mp.begin(); it != mp.end(); it++) {
room_num tmp;
tmp.a = it -> first;
tmp.c = it -> second;
rn.push_back(tmp);
}
sort(rn.begin(), rn.end(), cmp2);
for (int i = 0; i < rn.size(); i++) {
printf("%s %d\n", rn[i].a.c_str(), rn[i].c);
}
}
int main() {
int N, M;
cin >> N >> M;
for (int i = 0; i < N; i++) {
char s[14];
student tmp;
scanf("%s%d", s, &tmp.g);
tmp.id = s;
tmp.r = tmp.id.substr(0, 1); //note
tmp.a = tmp.id.substr(1, 3);
tmp.d = tmp.id.substr(4, 6);
tmp.num = tmp.id.substr(10, 3);
stu.push_back(tmp);
}
for (int i = 0; i < M; i++) {
int c, flag = 0;
char s[7];
string str;
scanf("%d%s", &c, s);
printf("Case %d: %d %s\n", i + 1, c, s);
str = s;
switch(c) {
case 1:
command1(str, flag); break;
case 2:
command2(str, flag); break;
default:
command3(str, flag);
}
if (flag == 0) {
printf("NA\n");
}
}
return 0;
}

题目来源:PAT乙级1095
作者:CHEN, Yue
单位:浙江大学

稀罕作者
Mengzhao Wang WeChat Pay

WeChat Pay

Mengzhao Wang Alipay

Alipay

# C/C++ # PAT # 编程
PAT乙级1094 || 谷歌的招聘(详解,C/C++示例,测试点分析)
M2LSH:基于LSH的高维数据近似最近邻查找算法-阅读笔记
  • Table of Contents
  • Overview
Mengzhao Wang

Mengzhao Wang

Try? All the way !
122 posts
6 categories
21 tags
  1. 1. 解码PAT准考证
    1. 1.1. 题目描述
    2. 1.2. 输入格式
    3. 1.3. 输出格式
    4. 1.4. 输入样例1
    5. 1.5. 输出样例1
    6. 1.6. 输入样例2
    7. 1.7. 输出样例2
    8. 1.8. 问题解决
      1. 1.8.1. 解题思想
      2. 1.8.2. 坑点提醒
      3. 1.8.3. 代码示例(C/C++)
© 2021 Mengzhao Wang