题解:首先需要记录当前已经入过栈的元素中最大元素的编号$pos$,然后分两种情况进行讨论,判断该元素是否满足出栈顺序。假设当前需要判断序列中的第$i$个数$x$是否符合条件。
-
首先,若栈为空或者栈顶元素小于$x$,说明此时$x$仍未在栈中,需要将$pos + 1$~$x$依次放入栈中,放入的过程需要不停的更新$pos$的值并保证$pos$不能超过$n$(随机序列的元素总数),同时需要判断是否栈中元素已经放满。
-
接着,判断当前栈顶元素是否为$x$,若为$x$,说明满足出栈条件,直接将$x$进行出栈操作。否则,该元素不符合出栈条件,有两种情况:
-
说明栈的容量不足,此时栈顶元素仍然小于$x$,在$x$要出栈前,无法放入$x$。
-
当前栈顶元素大于$x$,因为$x$小于当前栈顶元素,那么按照从小到大的入栈要求,说明$x$已经在栈里,但是$x$之上还有其他元素还未出栈,所以它无法出栈,也不满足要求。
-
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#define debug(x) cout << "***" << x << endl
using namespace std;
const int N = 1000;
int s[N + 5], a[N + 5];
int tot = 0, m, n, T;
int pos = 0; //表示当前已经进栈的最大元素序号
int check(int x)
{
while((!tot || s[tot] < x) && tot < m)
s[++tot] = ++pos; //在栈容量下将小于x还未入栈的元素入栈
if(s[tot--] == x) return 1; //栈顶元素为x
else return 0; //可能是栈不够放或者s.top > x
}
int main()
{
cin >> m >> n >> T;
while(T --)
{
int flag = 1;
tot = 0, pos = 0;
for(int i = 1; i <= n; i++) cin >> a[i];
for(int i = 1; i <= n && flag; i++)
flag = check(a[i]);
if(flag) cout << "YES" << endl;
else cout << "NO" << endl;
}
return 0;
}