2-10 出栈序列的合法性 (20 分)
给定一个最大容量为 M 的堆栈,将 N 个数字按 1, 2, 3, …, N 的顺序入栈,允许按任何顺序出栈,则哪些数字序列是不可能得到的?例如给定 M=5、N=7,则我们有可能得到{ 1, 2, 3, 4, 5, 6, 7 },但不可能得到{ 3, 2, 1, 7, 5, 6, 4 }。
输入格式:
输入第一行给出 3 个不超过 1000 的正整数:M(堆栈最大容量)、N(入栈元素个数)、K(待检查的出栈序列个数)。最后 K 行,每行给出 N 个数字的出栈序列。所有同行数字以空格间隔。
输出格式:
对每一行出栈序列,如果其的确是有可能得到的合法序列,就在一行中输出YES,否则输出NO。
输入样例:
5 7 5
1 2 3 4 5 6 7
3 2 1 7 5 6 4
7 6 5 4 3 2 1
5 6 4 3 7 2 1
1 7 6 5 4 3 2
结尾无空行
输出样例:
YES
NO
NO
YES
NO
这道题主要有两种解决方法,第一种不全面,只适用于题给的这种可以判断大小的情况,就是合法的出栈队列一定是所有数后面比它小的数都是递减排列的,因为它是按照1234567这样的顺序进栈的,所以如果进一个出一个出栈顺序还是1234567,但是如果有数字在栈里待着再出去的话那一定是按照先大后小的顺序出的,所以我们只要看每个数字后面比他小的数字是不是递减排列的就好了,数据结构就是,用一个数组存出栈队列,对这个数组进行一次检验就好了
#include<stdio.h>
int main()
{
int M,N,K;
int intex1,intex2;//intex1来表示这个数后面是否有比它小的数,intex2表示输出数列是否合法
int temp;//用来一直变化的表示寻到的数后最小的数,以便之后的数一直和它比较
int j,t;
scanf("%d%d%d",&M,&N,&K);
int a[N];
while(K--)
{
for(int i=0;i<N;i++)
scanf("%d",&a[i]);
intex2=0;//合法性标志在每次输入序列后设置
for(int i=0;i<N;i++)//开始一个一个数字的比较
{
t=0;//t用来表示不超过栈的最大序列,当遇到比它小的就加1,说明它在栈里待着占位置了
intex1=0;//这个标志放在这里,因为它表示的是每个数字后面有没有比它小的数字
for( j=i+1;j<N;j++)
if(a[j]<a[i])
{
t++;
if(t>=M)//注意比较的时候是大于等于M,因为在栈中的数有比它小的还得加上它自己,所以比它小的数等于M的时候就已经超过了,这时把标志置1
intex2=1;
temp=a[j];
intex1=1;
break;
}
if(intex1==1)//如果有的话就继续往后找,看比a[i]小的数有没有比temp小,是的话就把这个数置为temp,以便接下来的数和它比较
{
for(int k=j+1;k<N;k++)
{
if(a[k]<a[i])
{