XDOJ 305 判断堆栈出栈序列是否有效
- 问题描述
如果以序列“1,2,3,4”作为一个栈(初始为空)的输入,那么可得到输出序列“1,2,3,4”或“4,3,2,1”或“2,3,1,4”等等,但是肯定得不到输出序列“4,1,2,3”或“3,1,2,4”等等。请编写一个程序,判断能否通过一个栈得到给定的输出序列。
- 输入说明
每组数据由两行构成,第一行只有一个整数n(<10),表示序列长度,同时表示栈的输入序列为“1,2,3,…,n”;第二行为n个整数,表示需要判断的出栈序列,整数之间以空格分隔。
- 输出说明
输出一个yes或no(表示能否通过栈得到该序列)。
- 输入样例
6
3 4 2 1 5 6
- 输出样例
yes
.解决思路
入栈序列为1~n,出栈序列为题目所给定的序列
利用栈的性质分为一下三种情况:
(“i"指向出栈序列的元素,”j"指向入栈序列的元素。)
- 如果栈顶元素大于出栈序列元素:则说明出错,flag=0,退出循环。
- 如果栈顶元素小于出栈序列元素:则说明出栈序列元素还未入栈,此时应一直将入栈序列入栈(更新j值 j++)直到栈顶元素等于出栈序列元素。
- 如果栈顶元素等于出栈序列元素:说明匹配成功,将栈顶元素出栈,出栈序列的元素也后移一位开始检验下一个元素(i++)
如果最后栈空,且出栈序列已经被全部检测完,且入栈序列全部入过栈则说明成功,否则失败(flag=0)。 **其实可以不用这么多条件,为了保险起见,我就全加上了。
- 完整代码
#include<stdio.h>
int main()
{
int n,i,j,top,num;
int a[100],b[100],stack[100];
int flag=1;
top=0;//栈顶,入栈时栈顶加一再赋值,出栈时栈顶减一,top等于0时表示栈空
stack[top]=-10;//使第一次时栈顶元素小于出栈序列,从而入栈
scanf("%d",&n);
for(i=1;i<=n;i++)
{
a[i]=i;//入栈序列 123456
scanf("%d",&b[i]);//出栈序列 342156
}
num=n;
i=1;j=1;//从入栈序列和出栈序列的第一个元素开始
while(num!=0)//出栈序列没有检测完
{
if(b[i]<stack[top])//如果栈顶元素大于出栈序列元素:则说明出错,flag=0,退出循环。
{
flag=0;
break;
}
if(b[i]>stack[top])//栈顶元素小于出栈序列元素
{
while(b[i]>stack[top])//入栈,直到栈顶元素等于出栈序列
{
top++;
stack[top]=a[j++];
}
}
if(b[i]==stack[top])//栈顶元素等于出栈序列
{
top--;//出栈
i++;//出栈序列开始检验下一个
num--;//出栈序列还有num个(其实设置的num有点多余)
}
if(num==0&&top==0&&i==n+1&&j==n+1)// 如果最后栈空,且出栈序列已经被全部检测完,且入栈序列全部入过栈则说明成功
flag=1;
else
flag=0;
}
if(flag)
printf("yes");
else
printf("no");
return 0;
}