Pop Sequence
Pop Sequence
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
解题思路
做这题的时候找不到规律,所以最后索性直接用个栈来模拟,来判断各种情况的可能性。
第一次自己做的时候代码写得很复杂,不过还好的是一遍就AC了。
1 #include <cstdio> 2 3 int main() { 4 int m, n, k; 5 scanf("%d %d %d", &m, &n, &k); 6 bool ret[k]; // 用来存放输出结果,一开始并不知道输出结果可以在输入完成后就打印 7 int a[n], s[m], top = 0, last; // a数组用来存放判断序列,s数组用来模拟一个栈,last用来记录上一次压入栈的最后一个数 8 9 for (int i = 0; i < k; i++) { 10 ret[i] = true; 11 top = 0; 12 13 for (int j = 0; j < n; j++) { 14 scanf("%d", &a[j]); 15 } 16 17 if (a[0] > m) { // 序列中的第一个数就超过了栈的容量大小,直接标记为false并退出,判断下一组序列 18 ret[i] = false; 19 goto out; 20 } 21 22 for (int j = 1; j <= a[0]; j++) { // 把不大于序列中第一个数的所有数字压入栈中 23 s[top] = j; 24 top++; 25 } 26 last = a[0]; // last记录最后一次压入的数字,也就是序列的第一个数字a[0] 27 28 for (int j = 0; j < n; j++) { 29 if (s[top - 1] < a[j] || top == 0){ // 如果栈顶元素小于与序列比较的那个数,或者栈为空 30 for (int t = last + 1; t <= a[j]; t++) {// 就从last+1这个数开始,把不大于序列的那个数压入栈 31 if (top >= m) { // 如果在这个过程中超过栈的容量大小,直接标记为false并退出,判断下一组序列 32 ret[i] = false; 33 goto out; 34 } 35 else { // 如果没有超过栈的容量,则正常压入 36 s[top] = t; 37 top++; 38 } 39 } 40 last = a[j]; // last记录最后一次压入的数字 41 } 42 if (s[top - 1] == a[j]) { // 栈顶元素与序列中的那个数相同,则弹出来 43 top--; 44 } 45 else if (s[top - 1] > a[j]) { // 如果栈顶元素大于序列的那个数,直接标记为false并退出,判断下一组序列 46 ret[i] = false; 47 goto out; 48 } 49 } 50 51 out: continue; 52 } 53 54 for (int i = 0; i < k; i++) { 55 printf("%s\n", ret[i] ? "YES" : "NO"); 56 } 57 58 return 0; 59 }
下面的代码是参考别人的思路,并且自己稍加改进的代码。不得不说,大佬的思路真的太强了,代码比我的简洁多了。
1 #include <cstdio> 2 #include <stack> 3 4 int main() { 5 int m, n, k; 6 scanf("%d %d %d", &m, &n, &k); 7 8 while (k--) { 9 std::stack<int> S; 10 int t = n, num = 1; 11 bool flag = true; 12 13 while (t--) { 14 int x; 15 scanf("%d", &x); 16 17 if (flag) { 18 while (num <= x) { 19 S.push(num++); 20 } 21 22 if (S.top() != x || S.size() > m) flag = false; 23 S.pop(); 24 } 25 } 26 27 printf("%s\n", flag ? "YES" : "NO"); 28 } 29 30 return 0; 31 }
参考资料
[PAT解题报告] Pop Sequence:https://www.nowcoder.com/discuss/416
本文来自博客园,作者:onlyblues,转载请注明原文链接:https://www.cnblogs.com/onlyblues/p/14580344.html