声明:摘选自“ 算法竞赛入门经典(第2版)”作者: 刘汝佳 / 陈锋 ISBN:9787302291077
铁轨
某城市有一个火车站,铁轨铺设如图6-1所示。 有n节车厢从A方向驶入车站,按进站顺序编号为1~n。 你的任务是判断是否能让它们按照某种特定的顺序进入B方向的铁轨并驶出车站。 例如,出栈顺序(5 4 1 2 3)是不可能的,但(5 4 3 2 1)是可能的。
为了重组车厢,你可以借助中转站C。 这是一个可以停放任意多节车厢的车站,但由于末端封顶,驶入C的车厢必须按照相反的顺序驶出C。 对于每个车厢,一旦从A移入C,就不能再回到A了;一旦从C移入B,就不能回到C了。 换句话说,在任意时刻,只有两种选择:A→C和C→B。
解题思路
这是一个明显的栈问题,首先我们需要创建一个数组list来存放你给定的顺序,然后创建一个栈,来暂时存放按顺序进入c的数据。加入说你给定的数据时3、2、1、5、4。那么就是1、2、3按顺序进入栈,然后按照LIFO的规则即:3、2、1出栈,然后4、5按顺序入栈,按5、4出栈。说明是符合顺序的。这个问题的主要思路在于利用栈内数据跟你给定的数据逐个比较。因为规则的限定,入栈顺序一定是1、2、3、4、5,但是后面的数字没入栈之前,前面的数字可能已经出栈了。也就是说,我们不停地入栈,只要栈顶数据跟你给定的数据相同,我们就将其出栈,然后比较新的栈顶数据。
#include<iostream>
#include<stack>
using namespace std;
int n, list[50];
int main()
{
stack <int> s;
int a=1, b=1;
bool ok=1;
cin >> n;
for(int i=1; i<=n; i++)
{
cin >> list[i];
}
while(b < n)
{
if(a == list[b]) {a++; b++;}
else if(!s.empty() && s.top()==list[b]) {s.pop(); b++;}
else if(a <= n) s.push(a++);
else { ok=0; break;}
}
cout << endl;
if(ok) cout << "Yes"; else cout << "No";
return 0;
}