L2-1 出栈序列的合法性 (25 分)
给定一个最大容量为 M 的堆栈,将 N 个数字按 1, 2, 3, ..., N 的顺序入栈,允许按任何顺序出栈,则哪些数字序列是不可能得到的?例如给定 M=5、N=7,则我们有可能得到{ 1, 2, 3, 4, 5, 6, 7 },但不可能得到{ 3, 2, 1, 7, 5, 6, 4 }。
输入格式:
输入第一行给出 3 个不超过 1000 的正整数:M(堆栈最大容量)、N(入栈元素个数)、K(待检查的出栈序列个数)。最后 K 行,每行给出 N 个数字的出栈序列。所有同行数字以空格间隔。
输出格式:
对每一行出栈序列,如果其的确是有可能得到的合法序列,就在一行中输出YES
,否则输出NO
。
输入样例:
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
输出样例:
YES
NO
NO
YES
NO
* 思路:
* 出栈不合法的2个条件
* 1.栈容量溢出(通过统计出栈元素前面(比它值小的) 有多少个入栈了但还没出栈的元素就可以知道了,若个数+1(算上出栈元素自己)>M栈总容量)
* 2.提前出栈(还没到它出栈的顺序它就提前出栈了,通过判断出栈元素后面的(比它值大的)还有没有入栈了但还没出栈的元素,有的话证明提前出栈了)
/*
* 思路:
* 出栈不合法的2个条件
* 1.栈容量溢出(通过统计出栈元素前面(比它值小的) 有多少个入栈了但还没出栈的元素就可以知道了,若个数+1(算上出栈元素自己)>M栈总容量)
* 2.提前出栈(还没到它出栈的顺序它就提前出栈了,通过判断出栈元素后面的(比它值大的)还有没有入栈了但还没出栈的元素,有的话证明提前出栈了)
*/
import java.util.Scanner;
public class Main {
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
int m = scan.nextInt(); //容量
int n = scan.nextInt(); //个数
int k = scan.nextInt(); //测试数
String[] out = new String[k]; //结果
boolean flag = true;
for(int g = 0;g<k;g++) {
int sum = 0; //统计已经占用的栈空间
flag = true;
int[] f = new int[n+1]; //表示1——n是 没入栈 or 入栈但没出栈 or 出栈
// System.out.println("-----------------------------------------------");
for(int i = 0;i<n;i++) {
int a = scan.nextInt(); //逐次出入一组测试数据中的每一个数(输入一个判断一个)
f[a] = 1; //1出栈 0还没入栈 2已入栈但没出栈
sum = 0; //记录已入栈但没出栈的个数
for(int j = 1;j<=a;j++){
if(f[j]==0)
f[j] = 2; //前面还没入栈的都入栈
}
// for(int j = 1;j<=n;j++){
// System.out.print(f[j]+" ");
// }
// System.out.println();
for(int j = 1;j<=a;j++){
if(f[j]==2) { //统计出栈后,出栈元素前面的 还没出栈的了个数(也就是判断栈空间是否溢出)
sum++;
}
}
if(sum>=m) { //判断栈空间是否溢出
out[g] = "NO";
flag = false;
}
//判断出栈的元素其后面(也就是比他大的)的元素(已经入栈但还没出栈的元素)是否 有 还没有出栈
for(int j = a+1;j<=n;j++) {
if(f[j]==2) { //有没出栈的,则错误
out[g] = "NO";
flag = false;
}
}
}
if(flag) //表示正确
out[g] = "YES";
}
for(String s : out) {
System.out.println(s);
}
}
}