UVa514 解析:火车车厢重排序问题的模拟栈实现

来源:UVa514 铁轨 Rails。

这是一个火车车厢重排序的问题,通过模拟栈操作的算法实现。这种算法非常适用于具有栈结构特性的问题,比如括号匹配货物堆放编译器中语法检查。本文给出了C++的两种代码实现和Python的一种实现。

题目描述

某城市有一个火车站,铁轨铺设如图。有 n(n<=1000)n(n<=1000)n(n<=1000) 节车厢从A方向驶入车站,按进站的顺序编号为 1~n1~n1n 。你的任务是判断是否能让他们按照某种特定的顺序进入B方向的铁轨并驶出车站。例如,出站顺序 5 4 1 2 3 是不可能的,但 5 4 3 2 1 是可能的。

在这里插入图片描述
为了重组车厢,你可以借助中转站C。这是一个可以停放任意多节车厢的车站,但由于末端封顶,驶入C的车厢必须按照相反的顺序驶出C。对于每节车厢,一旦从A移入C,就不能返回A了;一旦从C移入B,就不能返回C了。也就是说,在任意时刻,只有两种选择:A到C和C到B。

输入

对于每一组数据,第一行是一个整数 NNN 。接下来若干行数据,每行 NNN 个数,代表 111 ~ NNN 车厢的出站顺序,每组最后一行数据只有一个整数 000

最后一组数据只有包含 000 的一行。

输出

对于每一组输入数据,除了第一行和最后一行,对于其它每行数据,如果是可能的出站顺序,则输出 Yes,否则输出 No。 每组最后输出空行。

最后一组数据的 N=0N=0N=0 ,不输出。

输入样例

5
1 2 3 4 5
5 4 1 2 3
0
6
6 5 4 3 2 1
0
0

输出样例

Yes
No

Yes

算法分析

核心算法思想是 借助栈来模拟火车车厢的出站过程,从而判断给定的出栈顺序是否可行。以下是该算法的详细分析。

问题描述

给定一列从编号 1n 的车厢,它们按顺序进入一个车站。车站的设计允许车厢进入一个中转站(即栈),但由于栈的后进先出(LIFO)性质,进入栈的车厢必须按相反的顺序出栈。我们希望判断给定的车厢出栈顺序是否可能实现。

算法思想

算法利用栈来模拟车站中转站的作用。对于给定的车厢出栈顺序,我们需要模拟车厢的进出站过程,遵循以下操作:

  1. 直接出站:如果当前车厢编号等于目标出栈顺序的当前编号,则该车厢无需进入中转站,直接出站。
  2. 中转站出栈:如果栈顶车厢符合当前的目标出栈顺序,则该车厢出栈,进入最终出站顺序。
  3. 中转站入栈:如果当前车厢编号不等于目标出栈顺序的当前编号,则将车厢推入栈中。
  4. 无解判定:当没有更多车厢可以入栈,且栈顶车厢不符合目标出栈顺序时,判断出栈顺序不可能实现。

算法复杂度分析

  • 时间复杂度O(n)O(n)O(n),因为每个车厢最多只会入栈一次、出栈一次。
  • 空间复杂度O(n)O(n)O(n),栈的最大空间需求为 n

算法适用场景

这种模拟栈操作的算法非常适用于具有栈结构特性的问题,比如:

  • 括号匹配(有效的括号序列)。
  • 货物堆放问题(货物按特定顺序出栈)。
  • 编译器中语法检查(例如词法分析器的匹配)。

总结

该算法利用栈结构的后进先出(LIFO)特点,以模拟火车车厢重排序问题,能够高效地判断是否可以通过合法的中转站操作实现目标出栈顺序。


代码实现

C++ 代码

1. 方法一
#include <iostream>
#include <string>
#include <stack>
#include <vector>
using namespace std;

bool isPossibleOrder(int n, const vector<int>& order) {
   
    stack<int> station;  // 模拟中转站C
    int currentA = 1;    // 进站的车厢编号从1开始
    int targetIndex = 0; // 出栈顺序的目标索引

    while 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值