铁轨(Rails, ACM/ICPC CERC 1997, UVa 514)
某城市有一个火车站,铁轨铺设如图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。
中转站C后进先出,是个栈
通过在C处入栈出栈,让A处的序列改变顺序,要判断能否通过一系列操作完成A B的匹配
#include<iostream>
#include<stack>
using namespace std;
int main()
{
int n;
while(cin>>n)
if(AB匹配)
cout<<"yes"<<endl;
else
return 0;
}
分析一下A B匹配有哪几种情况
- 12345 12345 A处输入的车厢节等于B处
- 当AB的车厢节数不相等时,AB要匹配就必须入栈
- 当栈顶元素等于B处时,弹出栈顶元素 判断第二节
- 处当前所指的元素不等于A处输入的车厢元素并且也不等于C的栈顶元素时,则将A处输入的车厢节压入栈(C)中
(1)当B处当前所指的元素不等于A处输入的车厢元素并且也不等于C的栈顶元素时,则将A处输入的车厢节压入栈(C)中;
(2)当A处输入的车厢节等于B处时,则可直接进行下一次操作,A、B都加一;
(3)当C栈的栈顶车厢节数等于B处并且栈不为空时,那么弹出C栈中的此元素,并且B加一,以进行下一次操作
(4)当上述三个条件都不满足时,则退出while输入循环。
#include<iostream>
#include<stack>
using namespace std;
const int maxn=1000+10;
int n; //火车编号
int target[maxn];
int main()
{
while(ciin>>n)
{
stack<int> s;
int a,b;
for(int i=0;i<=n;i++)
{
cin>>target[i];
}
int ok=1;
while(b<=n)
{
if(a==target[b]) //12345-12345
{
a++;
b++;
}
else if(!s.empty()&&s.top()==target[b]) //入栈后判断栈顶元素
{
s.pop();
b++;
}
else if(a<=n) s.push_back(a); //入栈
else
{
ok=0;
break;
}
}
cout<<(ok?"yes":"no")<<endl;
}
return 0;
}