OneCoder Avatar
OneCodercoderli.com · 957 篇博文
【CSP】CSP-J 2025真题 | 座位 luogu-P14358 (相当于GESP三、四级水平)📷 题解插图

【CSP】CSP-J 2025真题 | 座位 luogu-P14358 (相当于GESP三、四级水平)

📅 2026-02-02·✍️ OneCoder·计算中...·⏱️ 12 分钟
#CSP#C++#模拟#排序

CSP-J 2025真题- 座位,一维数组/排序考点,模拟思想,适合GESP三、四级考生练习,难度⭐⭐☆☆☆,洛谷难度等级普及−

P14358 [CSP-J 2025] 座位

题目要求

题目描述

CSP-J 2025 第二轮正在进行。小 R 所在的考场共有 n×mn \times m 名考生,其中所有考生的 CSP-J 2025 第一轮成绩互不相同。所有 n×mn \times m 名考生将按照 CSP-J 2025 第一轮的成绩,由高到低蛇形分配座位,排列成 nn mm 。具体地,设小 R 所在的考场的所有考生的成绩从高到低分别为 s1>s2>>sn×ms_1 > s_2 > \dots > s_{n \times m},则成绩为 s1s_1 的考生的座位为第 1 11 ,成绩为 s2s_2 的考生的座位为第 11 22 \dots,成绩为 sns_n 的考生的座位为第 11 nn ,成绩为 sn+1s_{n+1} 的考生的座位为第 22 nn \dots,成绩为 s2ns_{2n} 的考生的座位为第 22 11 ,成绩为 s2n+1s_{2n+1} 的考生的座位为第 33 11 ,以此类推。

例如,若 n=4,m=5n = 4, m = 5,则所有 4×5=204 \times 5 = 20 名考生将按照 CSP-J 2025 第一轮成绩从高到低的顺序,根据下图中的箭头顺序分配座位。

给定小 R 所在的考场座位的行数 nn列数 mm,以及小 R 所在的考场的所有考生 CSP-J 2025 第一轮的成绩 a1,a2,,an×ma_1, a_2, \dots, a_{n \times m},其中 a1a_1 为小 R CSP-J 2025 第一轮的成绩,你需要帮助小 R 求出,他的座位为第几第几

输入格式

输入的第一行包含两个正整数 n,mn, m,分别表示小 R 所在的考场座位的行数列数

输入的第二行包含 n×mn \times m 个正整数 a1,a2,,an×ma_1, a_2, \dots, a_{n \times m},分别表示小 R 所在的考场的所有考生 CSP-J 2025 第一轮的成绩,其中 a1a_1 为小 R CSP-J 2025 第一轮的成绩。

输出格式

输出一行两个正整数 c,rc, r,表示小 R 的座位为第 cc rr

输入输出样例 #1

输入 #1
Code 2 行
2 2
99 100 97 98
输出 #1
Code 1 行
1 2

输入输出样例 #2

输入 #2
Code 2 行
2 2
98 99 100 97
输出 #2
Code 1 行
2 2

输入输出样例 #3

输入 #3
Code 2 行
3 3
94 95 96 97 98 99 100 93 92
输出 #3
Code 1 行
3 1

说明/提示

【样例 1 解释】

按照成绩从高到低的顺序,成绩为 100100 的考生的座位为第 11 11 ,成绩为 9999 的考生的座位为第 11 22 ,成绩为 9898 的考生的座位为第 22 22 ,成绩为 9797 的考生的座位为第 22 11 。小 R 的成绩为 9999,因此座位为第 11 22

【样例 2 解释】

按照成绩从高到低的顺序,成绩为 100100 的考生的座位为第 11 11 ,成绩为 9999 的考生的座位为第 11 22 ,成绩为 9898 的考生的座位为第 22 22 ,成绩为 9797 的考生的座位为第 22 11 。小 R 的成绩为 9898,因此座位为第 22 22

【数据范围】

对于所有测试数据,保证:

  • 1n101 \leq n \leq 10, 1m101 \leq m \leq 10;
  • 对于所有 1in×m1 \leq i \leq n \times m,均有 1ai1001 \leq a_i \leq 100,且 a1,a2,,an×ma_1, a_2, \dots, a_{n \times m} 互不相同。
测试点编号 nn \leq mm \leq 特殊性质
11 11 11 AB
2,32, 3 11 1010
4,54, 5 1010 11
66 22 22 A
77 22 22 B
8,98, 9 22 22
1010 22 1010 A
1111 22 1010 B
121412 \sim 14 22 1010
151715 \sim 17 1010 22
182018 \sim 20 1010 1010

特殊性质 A:对于所有 1in×m1 \leq i \leq n \times m,均有 ai=ia_i = i

特殊性质 B:对于所有 1in×m1 \leq i \leq n \times m,均有 ai=n×mi+1a_i = n \times m - i + 1


题目分析

本题考查 模拟数学推导

1. 确定排名

题目要求根据成绩从高到低安排座位,且所有考生成绩互不相同。我们的目标是找到小 R 的位置。 首先,我们需要知道小 R 的成绩在所有考生中排第几名。

虽然可以直接将所有成绩存储下来并进行排序,但由于只关心小 R 一个人的位置,我们只需要统计 有多少个考生的成绩比小 R 高 即可。 设比小 R 成绩高的人数为 cnt,那么小 R 的排名就是 rank = cnt + 1

这种做法只需要遍历一遍输入数据,时间复杂度为 O(NM)O(NM),不仅实现简单,而且避免了排序带来的 O(NMlog(NM))O(NM \log(NM)) 复杂度(虽然本题数据范围较小,排序也完全可行)。

2. 坐标映射(蛇形填数)

知道了排名 rank,接下来就是将其映射到题目要求的“列”和“行”上。座位排列规则是“蛇形分配”:

  • 按列填充:前 nn 名在第一列,第 n+1n+12n2n 名在第二列,以此类推。
  • 奇数列(第 1, 3, 5... 列):从上往下填充(行号 1n1 \to n)。
  • 偶数列(第 2, 4, 6... 列):从下往上填充(行号 n1n \to 1)。

我们可以通过数学公式直接计算:

  1. 计算列号 cc: 每列容纳 nn 人。排名为 rank 的考生,处于第 c=rank/nc = \lceil rank / n \rceil 列。 在 C++ 中,利用整数运算的特性,可以使用 c = (rank - 1) / n + 1 来计算。

  2. 计算行号 rr: 先计算该考生在当前列是第几个位置(从 0 开始计数):pos = (rank - 1) % n

    • cc 是奇数:座位顺序是从上往下,行号即为 pos + 1
    • cc 是偶数:座位顺序是从下往上,行号为 n - pos

总结

这道题不需要复杂的二维数组模拟填充过程,通过简单的 计数确定排名,再配合 数学公式进行坐标变换 即可直接得出答案。核心代码逻辑清晰,适合作为 CSP-J 的签到题或简单模拟题。


示例代码

C++ 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;
}

💡 OneCoder 资源指引

所有代码开源上传至 GitHub:yummy-code 仓库 · GESP 专题站:GESP WIKI

🤝 技术交流与答疑

欢迎加入:C++ GESP/CSP 考级答疑群(688906745)Java/Python交流群(982860385),点击可直接加群。

📚

猜你想读 · 相关文章推荐

OneCoder

OneCoder (lihongzheshuai)

一个中年人的自留地,记录学习 C++、GESP/NOI、Java、Python 与算法架构的心得体会。本站唯一网址:coderli.com

读者讨论与留言

0 条讨论
✨ 支持点击留言直接回复 · Markdown 引用格式
💬 还没有读者留言,快来成为第一个讨论者吧!