Problem Description
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
Solution
思路启发自视频:PTA 出栈序列的合法性 (栈和队列的应用)
关键在于找到判断出栈顺序合法性的方法,这个方法具有普适性。
-
题意是说给定了一个序列,按照固定的相对顺序随意入栈,判断输入所给的出栈序列是否合法
-
我们需要构造一个固定的入栈相对顺序 order ,需要一个输入所给的待检验的出栈顺序 queue ,需要一个用来模拟的堆栈 stack
- 在这个题目中, stack 的容量、queue 的长度都已知。三个都可以用数组来存,但此题固定的相对顺序为自然数序列,我的 order 就没有用数组存而是直接用 int 递增的方式表示
-
算法思路(模拟):
- 从固定顺序逐个入栈 stack ,每入栈一个元素就将 stack 栈顶元素 top 与 queue 队首元素 front 进行比较,如果相等,模拟成功,栈顶元素出栈,队首元素出队,循环比对直到栈顶元素与队首元素不再相等
- 栈顶元素与队首元素不相等后,再次从固定顺序中入栈一个元素,继续进行以上比对方法
- 循环退出条件有:
- 整个序列模拟成功,front 最终值等于 n ,输出 YES
- 所有元素都入栈后遇到无法比对成功的一组栈顶元素和队首元素,但已经没有元素可入栈,order > n ,循环退出,输出 NO
- 遇不到一组能够比对成功的栈顶元素和队首元素,一直入栈直到爆栈循环退出,输出 NO
-
归根结底就是模拟成功输出 YES ,模拟失败输出 NO
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i, m, n, k, order, top, front;
int stack[1001], queue[1001];
scanf("%d %d %d", &m, &n, &k);
while (k--) {
for (i = 0; i < n; i++) scanf("%d", &queue[i]);
top = 0;
front = 0;
order = 1;
while (order <= n && top < m) {
stack[top] = order;
while (top >= 0 && front < n && queue[front] == stack[top]) {
top--;
front++;
}
top++;
order++;
}
if (front == n) printf("YES\n");
else printf("NO\n");
}
return 0;
}
以上是不用规范的数据结构与操作集实现的简易方法,毕竟数组操作比链表操作要简单。
也可以改成用规范的数据结构如 C++ 模板来实现算法,具有通用性。