铁轨(1997,UVa 514)
题意:顺序输入的若干正整数,经过一个栈后能否组成所给的出栈顺序
A,B应该都是队列的形式,C是栈,但队A,B都已经给定(比方说A就是1,2,3,4,5····这样的有序“队列”),可以视为数组一个个指过去
思路:做一个模拟配对的判断系统,循环大前提是“队”B没有到最后。显然,如果A已经指到最后且C也无法进行匹配(即C出栈成员与B当前成员相吻合),所给的顺序就是无法达成的。
{
Q:如果C空了,按照这个逻辑是不是也应该输出no?
大循环限制了这一点,在内部的头两个判断里,B++都会在栈空并执行判空前终止循环,所以让flag变0的只有一种可能:A指向尽头但栈C中有剩余成员,但C顶无法配对了
}
如何进行配对?
1.直来直往。A直出与B相同,比方A目前是1,2,3,4,5···中的第一个:1,B当前也是1,那么都指向下一个,回到大循环开始
2.也许需要入栈才能达成的。栈C需要非空,否则对于第一轮,无论如何C是空栈,无法取出成员与B比较。假如栈空,需要转3进行填充
那么非空的情况下,取出C顶,与B当前成员比较:
①c.top和B当前成员吻合:弹出栈顶,B指向下一个成员、
②不吻合:转3
3.若A还没有指向最后,将A压入栈C
代码如下:
#include<iostream>
#include<cstdio>
#include<stack>
using namespace std;
int n;
int target[100000];
int main()
{
int A=1,B=1;
int i;
int flag=1;
stack<int> s;
scanf("%d",&n);
for(i=1;i<=n;i++)
{
scanf("%d",&target[i]);
}
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);
A++;
}
else
{
flag=0;
break;
}
}
printf("%s\n",flag?"yes":"no");
return 0;
}