OpenJudge进栈出栈2
描述
1~N范围内的所有自然数按照从小到大的顺序(1,2,…,N)依次等待进栈。
比如现在N=3:
我们知道有些出栈顺序是合法的,例如{3,2,1}/{1,2,3}等
而有些出栈顺序是不可能出现(非法)的,例如{3,1,2}
现在给出1组出栈顺序,请你判断其是否合法。
输入
第1行包含1个整数N(1 <= N <= 20),代表元素个数。
第2行包含N的整数,代表出栈顺序,空格隔开。
输出
如果非法,输出“No”;
如果合法,输出“Yes”,以及在整个入栈/出栈过程中,栈的最大size,空格隔开
样例输入
样例1:
4
2 4 3 1
样例2:
4
2 4 1 3
样例输出
样例1:
Yes 3
//*合法,过程中{1,3,4}同时在栈中时size达到最大
样例2:
No
解题思路:
根据进栈和出栈的规律,我们可以利用栈还原实际的进出栈效果。先以数组读入数据,然后按顺序构建栈。对一个个元素分别进行分析,第一个数组元素可以直接进行读取,并且利用for循环进行从1一直到该元素入栈。当是第二个元素时我们要对其与前一个元素进行比较,如果大于的话继续存入数组,小于时进行判断是否与栈顶元素相同,不同则是错误的。每个元素分析完之后就得出了正确的答案。凡是错误的在上一步直接退出。
实现代码:
# include <stdio.h>
# include <stdlib.h>
#define ElemType int
#define maxsize 100
typedef struct {
ElemType data[maxsize];
int top;
}SqStack;
void InitStack(SqStack*& s)
{
s = (SqStack*)malloc(sizeof(SqStack));
if(s!=NULL) s->top = -1;
}
void DestroyStack(SqStack*& s)
{
free(s);
}
bool StackEmpty(SqStack*& s)
{
return (s->top == -1);
}
bool Push(SqStack*& s, ElemType e)
{
if (s->top == maxsize - 1)
return false;
s->top++;
s->data[s->top] = e;
return true;
}
bool Pop(SqStack*& s, ElemType &e)
{
if (s->top == -1)
return false;
e = s->data[s->top];
s->top--;
return true;
}
bool GetTop(SqStack* s, ElemType &e)
{
if (s->top == -1)
return false;
e = s->data[s->top];
return true;
}
int main ()
{
int i=0,n=0,j=0,size=0;
int flag=1;
SqStack*s; InitStack(s);
ElemType e,a[maxsize];
scanf("%d\n",&n);
for(i = 0; i < n; i++){
if(i==n-1) scanf("%d",&a[i]);
else scanf("%d ",&a[i]);
}
for(i = 0;i < n; i++){//代表对n各个进行分析
if(i==0){
for(j = 1;j <= a[i]; j++)//进栈的到第一个的位置
Push(s,j);
if((s->top+1)>size) size= s->top+1;
Pop(s,e); //出栈第一个元素
}
else {
if(a[i]>a[i-1]){ //如果第二个元素比前一个大,继续进栈
for( ; j <= a[i]; j++) //注意j是已经进栈过的数,只能累加
Push(s,j);
if((s->top+1)>size) size=s->top+1;//返回栈的个数
Pop(s,e);
}else if(a[i]<a[i-1]){
if(Pop(s,e)&&a[i]==e){ //判断元素与栈顶是不是一样的
int f=1;
}else{
flag=0;
printf("No\n");
system("pause");
return 0;
}
}
}
}
if(flag)
printf("Yes %d\n",size);
system("pause");
return 0;
}
记得点个赞哦