2 条题解

  • 0
    @ 2025-11-28 9:52:51

    这是一份经过验证的、可以直接提交的 C++ 参考代码。

    解题思路回顾

    1. 找排名:首先将所有人的成绩从大到小排序,找到小 R 的成绩排在第几名(记为 rank)。
    2. 定列号:每 nn 个人填满一列,所以列号 c=(rank1)/n+1c = (rank - 1) / n + 1
    3. 定行号
      • 算出该考生是这一列的第几个填入的:pos = (rank - 1) % n + 1
      • 奇数列(第 1, 3, 5...列):从上往下填(1n1 \to n),所以行号 r=posr = pos
      • 偶数列(第 2, 4, 6...列):从下往上填(n1n \to 1),所以行号 r=npos+1r = n - pos + 1

    参考代码 (C++)

    #include <iostream>
    #include <vector>
    #include <algorithm> // 用于 sort
    
    using namespace std;
    
    int main() {
        // 优化输入输出效率(虽数据量小,但养成好习惯)
        ios::sync_with_stdio(false);
        cin.tie(0);
    
        int n, m;
        if (!(cin >> n >> m)) return 0;
    
        // 总人数
        int total = n * m;
        
        // 使用 vector 存储所有成绩
        vector<int> scores(total);
        int my_score = -1; // 用于记录小 R 的成绩
    
        for (int i = 0; i < total; ++i) {
            cin >> scores[i];
            // 第一个输入的成绩是小 R 的
            if (i == 0) {
                my_score = scores[i];
            }
        }
    
        // 1. 将成绩从大到小排序
        // 使用 greater<int>() 实现降序排序
        sort(scores.begin(), scores.end(), greater<int>());
    
        // 2. 找到小 R 的排名 (从 1 开始)
        int rank = -1;
        for (int i = 0; i < total; ++i) {
            if (scores[i] == my_score) {
                rank = i + 1; // 下标是从0开始的,排名要+1
                break;
            }
        }
    
        // 3. 计算列号 c
        // 公式逻辑:每 n 个人一列,向上取整
        int c = (rank - 1) / n + 1;
    
        // 4. 计算行号 r
        // 先算出他在这一列是“第几个”放进去的
        int pos = (rank - 1) % n + 1;
        int r;
    
        if (c % 2 != 0) {
            // 奇数列 (1, 3, 5...):从上往下填 (1 -> n)
            // 所以位置就是行号
            r = pos;
        } else {
            // 偶数列 (2, 4, 6...):从下往上填 (n -> 1)
            // 比如 n=4,第1个放进去的在第4行,第2个在第3行...
            // 公式:n - pos + 1
            r = n - pos + 1;
        }
    
        // 输出结果:列号 行号
        cout << c << " " << r << endl;
    
        return 0;
    }
    

    代码关键点解析

    1. sort(..., greater<int>()):这是标准库提供的降序排序写法,比自己写 cmp 函数更方便。
    2. (rank - 1) / n + 1:这是计算“当前在第几组(第几列)”的经典数学公式,等同于 rank/n\lceil rank / n \rceil(向上取整)。
    3. c % 2 != 0:判断列号的奇偶性,是解决“蛇形”走向的关键。
    • 0
      @ 2025-11-28 9:51:23

      你好!这是 CSP-J 2025 的一道模拟/数学题。题目虽然描述了“蛇形”排列,看起来有点绕,但只要分步拆解,逻辑其实很清晰。

      这里给你提供解题的几个关键步骤提示:

      1. 第一步:确定排名(我是第几名?)

      题目说座位是按照“第一轮成绩由高到低”分配的。 这意味着你需要知道小 R 的成绩在所有考生中排第几。

      • 方法
        1. 读入数据时,先把小 R 的成绩(也就是输入的第一个数 a1a_1)专门存到一个变量里,比如叫 my_score
        2. 把所有考生的成绩数组进行从大到小排序(可以使用 sort 配合 greater<int>())。
        3. 遍历排序后的数组,找到 my_score 在其中的位置(下标)。记这个排名为 KK(注意:题目通常说第 1 名,所以如果是 0-based 下标,记得加 1)。

      2. 第二步:确定列号(我在第几列?)

      座位是先填满第 1 列,再填满第 2 列…… 这样一列一列填的。 每一列有 nn 个座位。

      • 假设你的排名是 KK
      • 你可以想象把人按顺序分组,每 nn 个人一组。
      • 公式推导
        • 1n1 \sim n 名在第 1 列。
        • n+12nn+1 \sim 2n 名在第 2 列。
        • ...
        • 列号 c=K/nc = \lceil K / n \rceil。在 C++ 整数运算中,可以写成 (K - 1) / n + 1

      3. 第三步:确定行号(我在该列的第几行?)

      这是题目唯一的难点:蛇形分布。 你需要判断当前列是奇数列还是偶数列,因为它们的填充方向不同。

      • 首先,算出你在这一列是“第几个”填入的。
        • 位置 pos = (K - 1) % n + 1
      • 分类讨论
        • 奇数列(1, 3, 5...):题目描述是“从第 1 行到第 nn 行”(从上往下)。
          • 这时,行号 rr 就是 pos
        • 偶数列(2, 4, 6...):题目描述是“从第 nn 行到第 1 行”(从下往上,倒着填)。
          • 这时,行号 rr 应该是倒过来的位置。想一想,如果总共 nn 行,第 1 个填入的人其实在第 nn 行,第 2 个在第 n1n-1 行...
          • 公式是:r=npos+1r = n - pos + 1

      4. 数据范围提示

      注意看数据范围:n,m10n, m \le 10。 这是一个非常非常小的数据。 这意味着:

      1. 你完全可以使用最朴素的排序和遍历。
      2. 甚至,如果你不想推导数学公式,你可以直接开一个二维数组 map[15][15],写个双重循环按照蛇形走位把所有名次填进去,最后遍历查找小 R 在哪里。这也是一种稳妥的满分做法。

      代码逻辑框架

      1. 输入 n, m 和所有成绩。
      2. 记录 target = a[1]。
      3. 对成绩数组进行降序排序。
      4. 找到 target 在数组中的排名 K (从1开始)。
      5. 计算列号 c = (K - 1) / n + 1。
      6. 计算该列的相对位置 pos = (K - 1) % n + 1。
      7. 判断 c 是奇数还是偶数:
          - 如果是奇数:r = pos
          - 如果是偶数:r = n - pos + 1
      8. 输出 c 和 r。
      

      加油!这是一道非常标准的数学模拟题。

      • 1

      信息

      ID
      19026
      时间
      1000ms
      内存
      32MiB
      难度
      3
      标签
      递交数
      1
      已通过
      1
      上传者