题解:洛谷 AT_abc463_b Train Reservation

【题目来源】

洛谷:AT_abc463_b [ABC463B] Train Reservation - 洛谷

【题目描述】

高桥正试图预订一列火车的座位。

他正在考虑预订候选的 \(N\) 列火车,这些火车编号为 \(1, 2, \dots, N\)。每列火车有五列座位,分别称为 A、B、C、D、E 列。

每列火车当前的座位空余信息由字符串 \(S_1, S_2, \dots, S_N\) 给出。每个 \(S_i\) 都是长度为 \(5\) 的字符串,火车 \(i\) 的 A、B、C、D、E 列分别对应 \(S_i\) 的第 1 到第 5 个字符。如果某个字符是 o,则对应列有空座位;如果该字符是 x,则对应列没有空座位。

高桥想要预订第 \(X\) 列的一个座位,这里 \(X\)A, B, C, D, E 中的一个。请判断是否至少有一列火车在第 \(X\) 列上有空座位。

【输入】

输入从标准输入读入,格式如下:

\(N\) \(X\)
\(S_1\)
\(S_2\)
\(\vdots\)
\(S_N\)

【输出】

如果至少有一列火车在第 \(X\) 列上有空座位,输出 Yes;否则输出 No

【输入样例】

3 A
xoxox
xxooo
oxxxx

【输出样例】

Yes

【核心思想】

  1. 问题分析:给定 \(N\) 趟列车,每趟列车有 \(5\) 列座位(A~E),用长度为 \(5\) 的字符串表示各列是否有空位(o 表示有空位,x 表示无空位)。需要判断是否存在至少一趟列车,其指定列 \(X\) 有空位。本质是二维矩阵的列查询问题。

  2. 算法选择

    • 直接模拟:将列字母 \(X\) 映射为数组下标,遍历 \(N\) 趟列车检查对应位置是否为 o
    • 提前终止:一旦找到有空位的列车即可确定答案,无需遍历全部
  3. 关键步骤

    • 读取输入\(N\)(列车数)、\(X\)(目标列)
    • 存储座位信息:读入 \(N\) 个长度为 \(5\) 的字符串,存入二维数组 \(a[1..N][1..5]\)
    • 列下标映射:目标列对应的数组下标为 \(idx = X - \texttt{`A'} + 1\)
    • 遍历查询:对 \(i\)\(1\)\(N\)
      • \(a[i][idx] = \texttt{`o'}\),标记找到并终止
    • 输出结果:找到输出 Yes,否则输出 No
  4. 时间/空间复杂度

    • 时间复杂度:\(O(N)\),最坏情况遍历所有列车,最好情况 \(O(1)\)(第一趟即有空位)
    • 空间复杂度:\(O(N \times 5) = O(N)\),存储 \(N\) 趟列车的座位信息
  5. 列映射与线性扫描的核心思想

    • 字符到索引的映射:利用 ASCII 码的连续性,通过 \(X - \texttt{`A'} + 1\) 将列字母 A~E 映射为 \(1\)~\(5\),避免手写 switchif-else 分支
    • 存在性查询:问题只关心"是否存在"而非"有多少"或"是哪些",因此设置布尔标记 flag,找到第一个满足条件的即可提前结束,优化平均时间
    • 二维数组的列访问:固定列下标、遍历行下标,实现对特定列的纵向扫描,体现了二维数据的行列组织方式
    • 输入解析策略:由于每行字符串无空格,使用 cin 按空白符分割即可正确读取,无需整行读取后再解析
    • 适用于二维表格的列查询、存在性判定、条件筛选等基础数据处理问题

【算法标签】

入门 #模拟

【代码详解】

#include <bits/stdc++.h>
using namespace std;
const int N = 105;              // 最大列车数量(N ≤ 100)
char a[N][6];                   // 存储每趟列车的座位信息,a[i][j] 表示第 i 趟列车的第 j 列
int n;                          // 列车数量
char x;                         // 目标列(A~E)

int main()
{
    cin >> n >> x;              // 读入列车数量 N 和目标列 X

    // 读入每趟列车的座位信息
    // 注意:这里用 cin >> 读取字符串时,每行会按空格/换行分割读入
    // 由于 S_i 长度为5且无空格,所以外层循环读 n 次,内层循环读 5 个字符
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= 5; j++)
            cin >> a[i][j];

    bool flag = false;          // 标记是否找到有空座位的列车
    for (int i = 1; i <= n; i++)
    {
        // 将列字母转换为数组下标:'A'->1, 'B'->2, ..., 'E'->5
        // 检查第 i 趟列车的 X 列是否为 'o'(有空座位)
        if (a[i][x - 'A' + 1] == 'o')
            flag = true;        // 找到至少一趟列车有空座位
    }

    if (flag)
        cout << "Yes" << endl;  // 至少有一趟列车的 X 列有空座位
    else
        cout << "No" << endl;   // 所有列车的 X 列都没有空座位

    return 0;
}

【运行结果】

3 A
xoxox
xxooo
oxxxx
Yes
posted @ 2026-07-01 21:37  团爸讲算法  阅读(11)  评论(0)    收藏  举报