Pop Sequence(25 分)
Given a stack which can keep M numbers at most. Push N numbers in the order of 1, 2, 3, ..., N and pop randomly. You are supposed to tell if a given sequence of numbers is a possible pop sequence of the stack. For example, if M is 5 and N is 7, we can obtain 1, 2, 3, 4, 5, 6, 7 from the stack, but not 3, 2, 1, 7, 5, 6, 4.
Input Specification:
Each input file contains one test case. For each case, the first line contains 3 numbers (all no more than 1000): M(the maximum capacity of the stack), N (the length of push sequence), and K (the number of pop sequences to be checked). Then K lines follow, each contains a pop sequence of N numbers. All the numbers in a line are separated by a space.
Output Specification:
For each pop sequence, print in one line "YES" if it is indeed a possible pop sequence of the stack, or "NO" if not.
Sample Input:
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
Sample Output:
YES
NO
NO
YES
NO
題目大意為給定一個入棧序列1,2,...,N,限定棧的大小為M,要求判斷輸出序列的合法性。編程小白的我開始想的是找出出棧序列有哪些特征,然后根據這些出棧序列的特征判斷一個棧的合法性。
可是弄了半天,寫出的程序又復雜又沒有什么條理,也沒用到棧結構,而且還通不過。。。明明想一想就能判別的東西,用程序寫出來總不盡人意。 無奈上網搜了一下大神們的博客,頓
覺豁然開朗。這道題考察的其實就是堆棧的基本概念和操作。比如說 5 6 4 3 7 2 1這個序列,首先我們自然由第一個出棧元素為5,推測出5出棧前棧里面應該為5 4 3 2 1(5為棧頂元素)。然
后5出棧,這時根據第二個元素為6知道,棧應該是繼續講6入棧的,此時棧頂元素等於6,將6出棧。依次類推,只要比較棧頂元素和將要出棧的元素的大小,就可以知道該進棧還是出棧。當
然,若是出現棧頂元素大於將要出棧的元素,或者雖然棧頂元素小於將要出棧的棧頂元素但此時棧已滿都說明這個將要出棧的元素是不可能出現的。因此可以判斷該出棧序列不合法。以上就是
根據出棧序列,推測出棧和入棧操作的過程,關鍵是比較棧頂元素與“將要出棧元素”的大小。根據大神們的博客的思路再結合自己的理解自己獨立地(就是沒有邊看邊寫^_^)寫出了如下的代碼。
1 #include<stdio.h> 2 #include<stdlib.h> 3 4 typedef struct Node { //c語言棧基本結構的構造 5 int *Data; 6 int Top; 7 int MaxSize; 8 }*Stack; 9 10 int M, N, K; //全局變量,放在棧結構后,方便子函數使用 11 12 Stack CreateStack(int MaxSize) { 13 Stack S = (Stack)malloc(sizeof(struct Node)); 14 S->Data = (int *)malloc(MaxSize * sizeof(int)); 15 S->Top = -1; 16 S->MaxSize = MaxSize; 17 return S; 18 } 19 20 void Push(Stack S, int ele) { 21 if (S->Top == S->MaxSize) { //短路寫法,遇錯就返回,提高程序可讀性 22 printf("FULL\n"); 23 return; 24 } 25 S->Data[++(S->Top)] = ele; 26 } 27 28 void Pop(Stack S) { 29 if (S->Top == -1) { 30 printf("Empty\n"); 31 return; 32 } 33 S->Top--; 34 } 35 36 int top(Stack S) { //返回棧頂元素 37 return S->Data[S->Top]; 38 } 39 40 int StackCheck(int *v,Stack S) { //檢查輸出序列是否為容量為M的棧輸出序列 41 int idx = 0; //數組v的指標,指向下一個將要出棧的元素 42 int num = 1; //按順序進棧的元素,進棧自動加1 43 S->Top = -1; 44 while (idx != N) { 45 while (S->Top != -1 && top(S)<v[idx]&&S->Top+1<M||S->Top==-1&&idx!=N) { 46 Push(S, num++); //若棧非空且棧頂元素小於將要比較的出棧元素或者棧為空且idx未滑至N(即出棧序列未比較完成) 47 } 48 if (S->Top!=-1&&top(S) == v[idx]) { //棧非空且棧頂元素值等於將要比較的出棧元素 49 Pop(S); 50 idx++; 51 } 52 if (S->Top != -1&&top(S)>v[idx]|| S->Top + 1 == M&&top(S) != v[idx]) { //棧非空且棧頂元素大於將要比較的出棧元素或棧滿但棧頂元素仍小於將要比較的出棧元素 53 return 0; //直接返回,使程序更易理解 54 } 55 } 56 57 return 1; 58 } 59 60 int main() { 61 int i, j; 62 Stack S; 63 64 scanf("%d %d %d", &M, &N, &K); 65 int *v = (int *)malloc(N * sizeof(int)); 66 S = CreateStack(M); 67 for (i = 0;i < K;i++) { 68 for (j = 0;j < N;j++) { 69 scanf("%d", v + j); 70 } 71 if (StackCheck(v, S)) 72 printf("YES\n"); 73 else 74 printf("NO\n"); 75 } 76 77 }