【问题描述】给出一个堆栈的输入序列,试判断一个序列是否能够由这个堆栈输出。如果能,返回总的出栈次数,如果不能,返回0。序列的输入及输出都是从左往右。(输入输出序列皆为整数且没有重复的数字,如果一个数字在输入序列中没有出现,那么其在输出序列中也不会出现)
【输入形式】第一行为输入序列的长度,然后为输入序列的数字;第二行为输出序列的数字。输入数据以空格隔开。
【输出形式】如果是一个出栈序列,则返回总的出栈次数, 否则返回0
【样例输入】
5 1 2 3 4 5
1 2 3 4 5
【样例输出】5
【样例说明】第一行输入的第一个数字是序列的长度,1 2 3 4 5 输入序列,以空格隔开,输出的总的出栈次数。
题解
核心思路:后进先出为逆序,意思是后进栈的在出栈序列序列中排在前,出栈序列就必然是逆序的。比如3124,在3后面比3小的数有1和2,则在出栈序列中1,2必须是逆序的,所以3124不是正确的出栈序列。
#include <iostream>
#define ElemType int
#define MAXSIZE 100
using namespace std;
int flag=0;
struct likestack1
{
int top;
ElemType date[MAXSIZE];
};
struct likestack2
{
int top;
ElemType date[MAXSIZE];
};
template <class T>
void initstack(T *S)
{
S->top=-1;
}
template <class T>
bool push(T *S,int a)
{
int e;
if(S->top==MAXSIZE-1)
{
return false;
}
for(int k=0;k<a;k++)
{
cin>>e;
S->top++;
S->date[S->top]=e;
}
return true;
}
template <class T>
bool stackempty(T *S)
{
if(S->top==-1)
{
return true;
}
else
{
return false;
}
}
template <class T>
bool pop(T *S,ElemType *e)
{
if(S->top==-1)
{
return false;
}
*e=S->date[S->top];
S->top--;
return true;
}
bool like(likestack2 *S2,int a)
{
for(int k=flag+1;k<a;k++)
{
if(S2->date[k]<S2->date[0]&&S2->date[k]>S2->date[flag])//比第一个元素小,却没有逆序
return false;
}
return true;
}
int main()
{
likestack1 *S1=new likestack1;
likestack2 *S2=new likestack2;
initstack(S1);
initstack(S2);
int a;
cin>>a;
push(S1,a);
push(S2,a);
for(int k=1;k<a;k++)
{
if(S2->date[k]<S2->date[0])
{
flag=k;//找到比第一个元素小的元素
if(like(S2,a)==false)
{
cout<<0;
return 0;
}
}
}
cout<<a;//出栈次数就是栈里元素的个数
return 0;
}