PTA 7-6 出棧序列的合法性

題目描述

給定一個最大容量爲 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

思路分析

一開始使用鏈表遇到了很多問題,後來發現用數組會簡單很多。
這個題可以分爲三種情況來判斷:第一種就是,元素入棧之後立刻出棧,那麼出棧序列的順序還是1,2,…,n的順序;第二種情況就是前k個元素一直入棧,然後開始出棧,那麼出棧序列的順序就是k,k-1,……,1;第三種情況就是前面這兩種情況的結合。
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
退出循環的條件是i>n或者A滿了,但是判斷是否退出循環的先決條件是i不等於B和A的pop不等於B。

源代碼

#include<stdio.h>
 
int m,n,k;
int stack[1007];       //棧 
int top=0;             //棧頂下標 
int index1=1,index2=1;     //index1來表示1-n的數字 ,index2來表示數組b的下標 
int b[1007];           //存放出棧序列 
 
int main()
{
    scanf("%d%d%d",&m,&n,&k);
    while(k--)
    {
    	int flag=1; 
    	index1=1;index2=1;
    	top=0; 
    	int i;
    	for(i=1;i<=n;i++)
    	  scanf("%d",&b[i]);
    	while(1)
    	{
    		//判斷給出的出棧序列如果和1到n增長順序相同,那就是入棧一個元素,然後立即出棧。 
    		if(index1==b[index2])
    		{
    			index1++;
    			index2++;
			}
			//判斷如果棧中有元素,然後棧頂元素也與此時的出棧序列元素相同,那麼就繼續出棧來判斷 
			else if(top!=0&&stack[top-1]==b[index2])
			{
				top--;
				index2++; 
			}
			else
			{
				if(index1>n)break;  //已經判斷結束,就跳出循環 
				stack[top]=index1;  //元素入棧 
				top++;
				index1++;
				if(top>=m) //
				{
					flag=0;
					break;
				}
			}
		}
		if(flag==0||top!=0)printf("NO\n");
		else printf("YES\n");
	}
    
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章