【CSP】CSP-J 2025真题 | 座位 luogu-P14358 (相当于GESP三、四级水平)
CSP-J 2025真题- 座位,一维数组/排序考点,模拟思想,适合GESP三、四级考生练习,难度⭐⭐☆☆☆,洛谷难度等级普及−。
P14358 [CSP-J 2025] 座位
题目要求
题目描述
CSP-J 2025 第二轮正在进行。小 R 所在的考场共有 $n \times m$ 名考生,其中所有考生的 CSP-J 2025 第一轮成绩互不相同。所有 $n \times m$ 名考生将按照 CSP-J 2025 第一轮的成绩,由高到低蛇形分配座位,排列成 $n$ 行 $m$ 列。具体地,设小 R 所在的考场的所有考生的成绩从高到低分别为 $s_1 > s_2 > \dots > s_{n \times m}$,则成绩为 $s_1$ 的考生的座位为第 1 列第 $1$ 行,成绩为 $s_2$ 的考生的座位为第 $1$ 列第 $2$ 行,$\dots$,成绩为 $s_n$ 的考生的座位为第 $1$ 列第 $n$ 行,成绩为 $s_{n+1}$ 的考生的座位为第 $2$ 列第 $n$ 行,$\dots$,成绩为 $s_{2n}$ 的考生的座位为第 $2$ 列第 $1$ 行,成绩为 $s_{2n+1}$ 的考生的座位为第 $3$ 列第 $1$ 行,以此类推。
例如,若 $n = 4, m = 5$,则所有 $4 \times 5 = 20$ 名考生将按照 CSP-J 2025 第一轮成绩从高到低的顺序,根据下图中的箭头顺序分配座位。
给定小 R 所在的考场座位的行数 $n$ 与列数 $m$,以及小 R 所在的考场的所有考生 CSP-J 2025 第一轮的成绩 $a_1, a_2, \dots, a_{n \times m}$,其中 $a_1$ 为小 R CSP-J 2025 第一轮的成绩,你需要帮助小 R 求出,他的座位为第几列第几行。
输入格式
输入的第一行包含两个正整数 $n, m$,分别表示小 R 所在的考场座位的行数与列数。
输入的第二行包含 $n \times m$ 个正整数 $a_1, a_2, \dots, a_{n \times m}$,分别表示小 R 所在的考场的所有考生 CSP-J 2025 第一轮的成绩,其中 $a_1$ 为小 R CSP-J 2025 第一轮的成绩。
输出格式
输出一行两个正整数 $c, r$,表示小 R 的座位为第 $c$ 列第 $r$ 行。
输入输出样例 #1
输入 #1
1
2
2 2
99 100 97 98
输出 #1
1
1 2
输入输出样例 #2
输入 #2
1
2
2 2
98 99 100 97
输出 #2
1
2 2
输入输出样例 #3
输入 #3
1
2
3 3
94 95 96 97 98 99 100 93 92
输出 #3
1
3 1
说明/提示
【样例 1 解释】
按照成绩从高到低的顺序,成绩为 $100$ 的考生的座位为第 $1$ 列第 $1$ 行,成绩为 $99$ 的考生的座位为第 $1$ 列第 $2$ 行,成绩为 $98$ 的考生的座位为第 $2$ 列第 $2$ 行,成绩为 $97$ 的考生的座位为第 $2$ 列第 $1$ 行。小 R 的成绩为 $99$,因此座位为第 $1$ 列第 $2$ 行。
【样例 2 解释】
按照成绩从高到低的顺序,成绩为 $100$ 的考生的座位为第 $1$ 列第 $1$ 行,成绩为 $99$ 的考生的座位为第 $1$ 列第 $2$ 行,成绩为 $98$ 的考生的座位为第 $2$ 列第 $2$ 行,成绩为 $97$ 的考生的座位为第 $2$ 列第 $1$ 行。小 R 的成绩为 $98$,因此座位为第 $2$ 列第 $2$ 行。
【数据范围】
对于所有测试数据,保证:
- $1 \leq n \leq 10$, $1 \leq m \leq 10$;
- 对于所有 $1 \leq i \leq n \times m$,均有 $1 \leq a_i \leq 100$,且 $a_1, a_2, \dots, a_{n \times m}$ 互不相同。
| 测试点编号 | $n \leq$ | $m \leq$ | 特殊性质 |
|---|---|---|---|
| $1$ | $1$ | $1$ | AB |
| $2, 3$ | $1$ | $10$ | 无 |
| $4, 5$ | $10$ | $1$ | 无 |
| $6$ | $2$ | $2$ | A |
| $7$ | $2$ | $2$ | B |
| $8, 9$ | $2$ | $2$ | 无 |
| $10$ | $2$ | $10$ | A |
| $11$ | $2$ | $10$ | B |
| $12 \sim 14$ | $2$ | $10$ | 无 |
| $15 \sim 17$ | $10$ | $2$ | 无 |
| $18 \sim 20$ | $10$ | $10$ | 无 |
特殊性质 A:对于所有 $1 \leq i \leq n \times m$,均有 $a_i = i$。
特殊性质 B:对于所有 $1 \leq i \leq n \times m$,均有 $a_i = n \times m - i + 1$。
题目分析
本题考查 模拟 和 数学推导。
1. 确定排名
题目要求根据成绩从高到低安排座位,且所有考生成绩互不相同。我们的目标是找到小 R 的位置。 首先,我们需要知道小 R 的成绩在所有考生中排第几名。
虽然可以直接将所有成绩存储下来并进行排序,但由于只关心小 R 一个人的位置,我们只需要统计 有多少个考生的成绩比小 R 高 即可。 设比小 R 成绩高的人数为 cnt,那么小 R 的排名就是 rank = cnt + 1。
这种做法只需要遍历一遍输入数据,时间复杂度为 $O(NM)$,不仅实现简单,而且避免了排序带来的 $O(NM \log(NM))$ 复杂度(虽然本题数据范围较小,排序也完全可行)。
2. 坐标映射(蛇形填数)
知道了排名 rank,接下来就是将其映射到题目要求的“列”和“行”上。座位排列规则是“蛇形分配”:
- 按列填充:前 $n$ 名在第一列,第 $n+1$ 到 $2n$ 名在第二列,以此类推。
- 奇数列(第 1, 3, 5… 列):从上往下填充(行号 $1 \to n$)。
- 偶数列(第 2, 4, 6… 列):从下往上填充(行号 $n \to 1$)。
我们可以通过数学公式直接计算:
计算列号 $c$: 每列容纳 $n$ 人。排名为
rank的考生,处于第 $c = \lceil rank / n \rceil$ 列。 在 C++ 中,利用整数运算的特性,可以使用c = (rank - 1) / n + 1来计算。计算行号 $r$: 先计算该考生在当前列是第几个位置(从 0 开始计数):
pos = (rank - 1) % n。- 若 $c$ 是奇数:座位顺序是从上往下,行号即为
pos + 1。 - 若 $c$ 是偶数:座位顺序是从下往上,行号为
n - pos。
- 若 $c$ 是奇数:座位顺序是从上往下,行号即为
总结
这道题不需要复杂的二维数组模拟填充过程,通过简单的 计数确定排名,再配合 数学公式进行坐标变换 即可直接得出答案。核心代码逻辑清晰,适合作为 CSP-J 的签到题或简单模拟题。
示例代码
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
#include <iostream>
int main() {
int n, m;
std::cin >> n >> m;
int target;
std::cin >> target; // 小R的成绩,即第一个输入的成绩
int rank = 1;
// 只需要知道有多少人比小R成绩高,就能确定小R是第几名
// 输入剩下的 n*m - 1 个成绩
for (int i = 1; i < n * m; ++i) {
int score;
std::cin >> score;
if (score > target) {
rank++;
}
}
// 题目中座位是按成绩从高到低排列
// rank 就是小R在排序后的索引(1-based)
// 计算列号 col
// 每一列有 n 行,蛇形填数
// 第 1 列填 1..n 名
// 第 2 列填 n+1..2n 名
// ...
// 所以 col = ceil(rank / n)
int col = (rank - 1) / n + 1;
// 计算行号 row
// 如果 col 是奇数,从上往下填 (1 -> n)
// 如果 col 是偶数,从下往上填 (n -> 1)
// 在当前列中的相对位置 (0-based offset for simple math)
int pos_in_col = (rank - 1) % n;
int row;
if (col % 2 != 0) { // 奇数列:1, 3, 5... 从上往下
// pos_in_col 0 -> row 1
// pos_in_col n-1 -> row n
row = pos_in_col + 1;
} else { // 偶数列:2, 4, 6... 从下往上
// pos_in_col 0 -> row n
// pos_in_col n-1 -> row 1
row = n - pos_in_col;
}
std::cout << col << " " << row << std::endl;
return 0;
}
所有代码已上传至Github:https://github.com/lihongzheshuai/yummy-code
GESP 学习专题站:GESP WIKI
“luogu-”系列题目可在洛谷题库进行在线评测。
“bcqm-”系列题目可在编程启蒙题库进行在线评测。
欢迎加入:Java、C++、Python技术交流QQ群(982860385),大佬免费带队,有问必答
欢迎加入:C++ GESP/CSP认证学习QQ频道,考试资源总结汇总
欢迎加入:C++ GESP/CSP学习交流QQ群(688906745),考试认证学员交流,互帮互助

