题目来源: NEFU OJ 栈-火车编组 详细链接已补

OP
oj中没有配图,我就没有 想透 题,最后查到这里才完全理解,下面的示意图亦出自该帖。
大体思路
以样例为例,题意即为将A端(左至右)1,2,3,4,通过编组站调至B端(左至右)3,2,4,1。
我们可以将轨道中段视为栈,从A方向入栈,向B方向出栈。
决定出栈还是继续入栈的判据即为目前栈顶元素与目标车厢编号的大小关系:
——如果小于目标车厢编号,则继续从A端入栈;
——如果等于,则出栈进行编组;
——如果大于,则请看下一个二级目录。
某车厢出栈编组后,目标车厢编号即变为目标序列的下一元素,直至目标序列被编组完毕。
有关限定条件的想法
无论是在oj中,还是图源帖中,对题目的描述始终没有明确入栈的车厢是否可以出栈至A端,但是就我的判断,题目中不能。
图源帖中的问题是判断目标序列能否达成,如果能出栈至A端,则不存在非法序列。同理,oj经测试,所有测试组均合法。
对于图源帖中的问题,如果目前栈顶元素大于目标车厢编号,则可判断该序列非法。若考虑可以出栈至A端,则可以出栈至A端等待再次入栈。
代码
#include <bits/stdc++.h>
using namespace std;
int main()
{
stack<int>ord;//ord为A端
stack<int>sta;//sta为编组用栈
int aim[105],process=1;//aim记录目标序列,
//process记录目标车厢编号
int n,i;
cin>>n;
for(i=1;i<=n;i++)
cin>>aim[i];
for(i=n;i>=1;i--)
ord.push(i);
while(process!=n+1)
{
if(!sta.empty()&&sta.top()>aim[process])
{
/*ord.push(sta.top());这段注释掉的是出栈至A端
sta.pop();
cout<<'B';*/
}
else if(sta.empty()||sta.top()<aim[process])
{
sta.push(ord.top());
ord.pop();
cout<<'A';
}
else if(sta.top()==aim[process])
{
sta.pop();
cout<<'B';
process++;//目标车厢改为下一个
}
}
return 0;
}
ED
另:对于空栈使用.top会RTE。