题解:洛谷 AT_abc463_b Train Reservation

【题目来源】

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

【题目描述】

Takahashi is trying to reserve a seat on a train.

There are \(N\) trains he is considering as candidates for reservation, numbered \(1, 2, \dots, N\). Each train has seats in five columns, called column A, column B, column C, column D, and column E.

The current seat availability information for each train is given as strings \(S_1, S_2, \dots, S_N\). Here, \(S_1, S_2, \dots, S_N\) all have length \(5\), and columns A through E of train \(i\) correspond to the first through fifth characters of \(S_i\), respectively. If that character is o, there is a vacant seat in the corresponding column; if it is x, there is no vacant seat in the corresponding column.

Takahashi wants to reserve a seat in column \(X\), where \(X\) is one of A, B, C, D, E. Determine whether there is a vacant seat in column \(X\) on at least one train.

高橋正在尝试预订列车座位。

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

每趟列车当前的座位可用情况由字符串 \(S_1, S_2, \dots, S_N\) 给出。这里,\(S_1, S_2, \dots, S_N\) 的长度均为 \(5\),列车 \(i\) 的 A 到 E 列分别对应 \(S_i\) 的第 \(1\) 到第 \(5\) 个字符。如果该字符为 o,表示对应列有空座位;如果为 x,表示对应列没有空座位。

高橋想要在 \(X\) 列预订一个座位,其中 \(X\)ABCDE 中的一个。请判断至少有一趟列车的 \(X\) 列存在空座位。

【输入】

The input is given from Standard Input in the following format:

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

【输出】

If there is a vacant seat in column \(X\) on at least one train, output Yes; otherwise, output 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  团爸讲算法  阅读(7)  评论(0)    收藏  举报