浙大 PAT A1051 Pop Sequence

Problem

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.
意思就是说有一个栈,最大为M,输入K个从1到N的乱序。然后判断这个序列是不是该栈的合法输出。

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.
输入时,第一行是三个数字,都小于1000,M表示栈最大的容量,N表示乱序序列的长度,K表示有几个乱序序列。每个数字之间都用一个空格分隔。

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.
输出YES表示是栈的合法输出,输出NO表示非法输出。

My Solution

我的思路是这样的:
对每一个序列,
第一个数如果大于M,输出序列非法,否则入栈。
然后从第二个元素开始比较,如果这个元素比栈顶的元素大,那么这个元素与栈顶元素的差必须小于等于M,否则该序列非法。
如果这个元素比栈顶元素小,那么它必须是这N个元素里面还未出现的最大元素,否则该序列非法。
(我个人觉得没问题,但是不能的满分,PAT得24分,差一分。欢迎指正。)

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <math.h>
#include <time.h>
#include <algorithm>
#include <iostream>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cstring>
#include <map>
#include <iterator>
using namespace std;
#pragma warning(disable:4996)

int main()
{
	stack<int>b;
	int m = 0;
	int n = 0;
	int k = 0;
	cin >> m >> n >> k;
	int c[1000][1000] = { 0 };
	bool d[1000] = { 0 };
	queue<int*>a;    //队列的元素是大小为n的数组
	if (m < 0 || m>1000) {
		return -1;
	}
	if (n < 0 || n>1000) {
		return -1;
	}
	if (k < 0 || k>1000) {
		return -1;
	}
	for (int i = 0; i < k; i++) {
		for (int j = 0; j < n; j++) {
			cin >> c[i][j];
		}
		a.push(c[i]);
	}
	for (int i = 0; i < k; i++) {
		while (!b.empty()) { b.pop(); }
		memset(d, 0, 1000);
		if (a.front()[0] > m) {
			cout << "NO" << endl;
		}
		else {
			b.push(a.front()[0]);
			d[a.front()[0] - 1] = true;
			for (int j = 1; j < n; j++) {
				if (a.front()[j] > b.top()) {
					if (a.front()[j] - b.size() <= m && j == 6) { cout << "YES" << endl; break; }
					if (a.front()[j] - b.size() <= m) { b.push(a.front()[j]); d[a.front()[j] - 1] = true; }
					else { cout << "NO" << endl; break; }
				}
				else if (a.front()[j] < b.top()) {
					int i1 = 0;
					for (i1 = b.top() - 1; i1 >= 0; i1--) {
						if (d[i1] == false)  break;
					}
					if (i1 > -1) {   //此处这个if其实可以省略,这里的每个数都会出现。
						if (a.front()[j] == i1 + 1 && j == 6) { cout << "YES" << endl; break; }
						if (a.front()[j] == i1 + 1) { b.push(a.front()[j]); d[a.front()[j] - 1] = true; }
						else { cout << "NO" << endl; break; }
					}
					else { cout << "NO" << endl; break; }
				}
				else { cout << "NO" << endl; break; }   //这个else也可以不要。
			}
		}
		a.pop();
	}
	return 0;
}

我这里采用的是先把输入全部完成,存储所有的输入,然后开始一个一个计算,但是,其实不需要这样也可以。不用存储所有的输入,输入一个计算一个也可以。算法笔记解这道题采用的就是这个方法。

算法笔记的解法

思路:让1-n按顺序入栈,如果当前刚入栈的数和输入序列的当前指针指向的数相等,则刚入栈的数出栈,并且输入序列的指针后移一位。如果入栈后,栈的大小大于M了,就返回错误。

#include <cstdio>
#include <stack>
using namespace std;
const int maxn = 1010;
int arr[maxn];
stack<int> st;
int main() {
    int m, n, T;
    scanf("%d%d%d", &m, &n, &T);  //这里没有判断输入是否合法,PAT有时会考虑这个。
    while(T--) {
        while(!st.empty()) {
            st.pop();
        }
        for(int i = 1; i <= n; i++) {
            scanf("%d", &arr[i]);
        }
        int current = 1;
        bool flag = true;
        for(int i = 1; i <= n; i++) {
            st.push(i);
            if(st.size() > m) {
                flag = false;
                break;
            }
            while(!st.empty() && st.top() == arr[current]) {
                st.pop();
                current++;
            }
        }
        if(st.empty() == true && flag == true) {
            printf("YES\n");
        } else {
            printf("NO\n");
        }
    }
    return 0;
}

这个方法是满分,并且比我的简单,他利用栈来实现判断,其实和我的思路本质上是一样的,只是他的更加精简。
谢谢阅读!

发布了27 篇原创文章 · 获赞 0 · 访问量 405

猜你喜欢

转载自blog.csdn.net/weixin_40007143/article/details/104171451