题解:洛谷 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
【核心思想】
-
问题分析:给定 \(N\) 趟列车,每趟列车有 \(5\) 列座位(A~E),用长度为 \(5\) 的字符串表示各列是否有空位(
o表示有空位,x表示无空位)。需要判断是否存在至少一趟列车,其指定列 \(X\) 有空位。本质是二维矩阵的列查询问题。 -
算法选择:
- 直接模拟:将列字母 \(X\) 映射为数组下标,遍历 \(N\) 趟列车检查对应位置是否为
o - 提前终止:一旦找到有空位的列车即可确定答案,无需遍历全部
- 直接模拟:将列字母 \(X\) 映射为数组下标,遍历 \(N\) 趟列车检查对应位置是否为
-
关键步骤:
- 读取输入:\(N\)(列车数)、\(X\)(目标列)
- 存储座位信息:读入 \(N\) 个长度为 \(5\) 的字符串,存入二维数组 \(a[1..N][1..5]\)
- 列下标映射:目标列对应的数组下标为 \(idx = X - \texttt{`A'} + 1\)
- 遍历查询:对 \(i\) 从 \(1\) 到 \(N\):
- 若 \(a[i][idx] = \texttt{`o'}\),标记找到并终止
- 输出结果:找到输出
Yes,否则输出No
-
时间/空间复杂度:
- 时间复杂度:\(O(N)\),最坏情况遍历所有列车,最好情况 \(O(1)\)(第一趟即有空位)
- 空间复杂度:\(O(N \times 5) = O(N)\),存储 \(N\) 趟列车的座位信息
-
列映射与线性扫描的核心思想:
- 字符到索引的映射:利用 ASCII 码的连续性,通过 \(X - \texttt{`A'} + 1\) 将列字母
A~E映射为 \(1\)~\(5\),避免手写switch或if-else分支 - 存在性查询:问题只关心"是否存在"而非"有多少"或"是哪些",因此设置布尔标记
flag,找到第一个满足条件的即可提前结束,优化平均时间 - 二维数组的列访问:固定列下标、遍历行下标,实现对特定列的纵向扫描,体现了二维数据的行列组织方式
- 输入解析策略:由于每行字符串无空格,使用
cin按空白符分割即可正确读取,无需整行读取后再解析 - 适用于二维表格的列查询、存在性判定、条件筛选等基础数据处理问题
- 字符到索引的映射:利用 ASCII 码的连续性,通过 \(X - \texttt{`A'} + 1\) 将列字母
【算法标签】
入门 #模拟
【代码详解】
#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
浙公网安备 33010602011771号