紫书140例题6-2 铁轨&&UVa514
某城市有一个火车站,铁轨铺设如图6-1所示。有n节车厢从A方向驶入车站,按进站顺序编号为1~n。你的任务是判断是否能让它们按照某种特定的顺序进入B方向的铁轨,并驶出车站。例如,出栈顺序(5 4 1 2 3)是不可能的,但(5 4 3 2 1)是可能的。
为了重组车厢,你可以借助中转站C。这是一个可以停放任意多节车厢的车站,一旦从A移入C,就不能再回到A了,一旦从C移入B,就不能再回到C了。换句话说,在任意时刻,只有两种选择,A->C和C->B.
分析:在中转站C中,车厢符合后进先出的原则,因此是一个栈。用两个变量模拟车辆进站出站,A和B。进站是按照1~n的顺序。第i辆车进站时,会出现三种情况,它进去了直接出来,就是A==target[B];(B是当前出站的车辆)或者,它还没进站,上一次进入的车辆出站了,!s.empty()&&s.top()==target[B];或者是,他进去了 就是直接把这辆车push进队列 s.push(A++);
代码如下:
#include <cstdio> #include <stack> using namespace std; const int MAXN=1000+10; int n,target[MAXN]; int main(){ while(scanf("%d",&n)==1){ stack<int> s; int A=1,B=1; for(int i=1;i<=n;i++) scanf("%d",&target[i]); int ok=1; while(B<=n){ if(A==target[B]){A++,B++;} else if(!s.empty()&&s.top()==target[B]){s.pop();B++;} else if(A<=n) s.push(A++); else {ok=0;break;} } printf("%s\n",ok?"Yes":"No"); } return 0; }