Files
BH-ICPC-Management-System-2023/Michelle/README.md
indigolxy 18e12a89c0 init
2023-10-05 13:12:24 +08:00

137 lines
4.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Michelle 的学生会工作
[评测地址](https://acm.sjtu.edu.cn/OnlineJudge/problem?problem_id=1346)
## 1 背景
Michelle 接到了花咲川学生会的协助请求,想要她帮忙写一个程序管理学生的信息。但她还有 `Hello, Happy World` 新曲的编曲没有完成,实在是没有时间了。你能帮帮她吗?
## 2 题目目的
本题目为 ICPC Management System 的前置作业,意在确保大家掌握结构体与部分 STL 容器的基本操作。
## 3 任务描述
在这个任务中,你需要实现一个管理系统,通过控制台输入对学生信息进行维护。
题目保证:
* 输入格式合法
* 在开始统计前只会出现 `ADD` 操作
* `START` 操作仅出现一次
具体需要实现以下操作。
### 添加学生
```
ADD <name> <gender> <class> <score0> ... <score8>
```
向系统中添加一名学生。学生有 12 个参数,`name``gender``class` 与 9 个成绩。
* `name`为长度不超过 30 的字符串,由数字、大小写字母与下划线组成;
* `gender` 为一个字母,`M` 代表男性,`F` 代表女性;
* `class` 为 $[1,20]$ 内的一个整数;
* `scorei` 为课程代号为 ii = 0, 1, ..., 8的课程的得分得分为 $[1,100]$ 内的一个整数。
开始统计后不能再添加学生。若已经开始统计,输出 `[Error]Cannot add student now.`;若未开始统计但学生名字重复输出 `[Error]Add failed.`
本题中,添加失败只有一种情况,即学生名字重复。
### 开始统计
```
START
```
开始进行学生的成绩统计。在开始统计时,榜单应该按照顺序排列。
### 更新成绩
```
UPDATE <name> <code> <score>
```
更新学生 `name` 课程代号为 `code` 的分数为 `score`。保证 `score` 为 $[0,100]$ 内的整数,`code` 为 $[0,8]$ 内的整数。
若学生不存在输出 `[Error]Update failed.`
### 刷新榜单
```
FLUSH
```
刷新榜单。**注意更改学生成绩但未刷新榜单时榜单的排名不会变化**(但数据可能变化)。
### 输出榜单
```
PRINTLIST
```
输出共 N学生总数每行以
```
<rank> <name> <gender> <class> <avg_score>
```
的格式输出,其中 `rank``1-based``gender` 男性输出`male`,女性输出 `female``avg_score` 为该学生所有分数的平均值,向下取整。
学生的排名由平均成绩(即 `avg_score`,注意为向下取整的平均成绩)决定,平均成绩高者靠前;平均成绩相同时从 0 到 8 分别比较成绩,成绩高者靠前;依旧平局时,比较学生名字的字典序,字典序较小者靠前。
### 查询学生排名
```
QUERY <name>
```
若学生存在,以
```
STUDENT <name> NOW AT RANKING <ranking>
```
的格式输出学生的排名1-based。否则输出 `[Error]Query failed.`
### 退出程序
```
END
```
结束程序。
## 4 数据范围
学生总数为 $n$ ,操作次数为 $\mathit{opt}$ 。
对于 60% 数据, $n\le 100$ $\mathit{opt}\le 3\times 10^3$ 。​​
对于 100% 数据, $n\le 10^4$ $\mathit{opt}\le 3\times 10^5$ ​。​
## 5 提示
在这道题目中,你应该使用一个 `struct` 去保存所有学生的信息,并使用一个 `string` 到该结构体的 `map` 来维护学生的信息;同时,你需要使用 `set` 维护一个排行榜,排序标准为学生的成绩。
`map``set` 的相关接口可以在 cpp reference 上学习。
本目录下的 `data` 文件夹即 Online Judge 上的测试数据点。
`START` 之后,各个指令出现的频率大致如下:
* `UPDATE` 45%
* `QUERY` 45%
* `ADD` 5%
* `FLUSH` 4.9%
* `PRINTLIST` 0.1%
如果你遇到 `Time Limit Exceed` 的问题,可以考虑以下几种优化方法。
*`map` 换成 `unordered_map`。这两个容器在接口上十分相似,且均实现了映射的功能,但 `unordered_map` 的性能较好。(相应的,`unordered_map` 牺牲了容器内元素的有序性。)
* 避免使用函数的值传递,改成 `const &` 传递。
* 你是否在 `map``set` 中各保存了一份学生信息?对于冗余信息的大量移动与复制是十分消耗时间的。可以在 `set` 中只保存少量元素,例如只保存学生名字,或者使用一个数组或者 `vector` 来存放学生的信息,`map``set` 都只存放学生在 `vector` 中的位置。
* 你是否每次 QUERY 指令都要从头遍历一遍 `set`?这个操作的时间复杂度是 $O(n)$ 的,对于占比 45% 的 QUERY 指令来说是一个不可接受的复杂度。可以尝试把这个排名存下来,输出的时候直接去调用。
* 对于 FLUSH 指令,你是否在执行时将 `set` 清空并全部重新插入?你可以试试在 UPDATE 时就维护正确的排名。注意,当 `set` 中的元素值变化后,其在容器中的位置 **不会** 及时更新;你可以通过把这个元素 erase 之后重新 insert 来刷新这个元素的位置。