目录
1,题目描述
题目大意
2,思路
关键点
3,代码
1,题目描述
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
题目大意
题意比较明确:模拟栈的功能,1-N依次随机入栈或出栈,判断给定序列是否为出栈序列的一种。此外还限制栈的大小为M。
2,思路
(一开始看见这道题,内心无比兴奋,因为数据结构作业做过类似的,好像有一个什么规律。。。然而没多久,笑容便开始僵硬,我忘了是什么规律了,,,心态崩裂,连模拟都没心情了,使劲地想,越想越做不出来。最后无奈只好先跳过。。。)
其实本题的数据量并不大,直接模拟也不难。(规律在网上暂时没找到,日后找到了再来分享)
关键点
1,声明两个vector<int> stac, check数组来模拟栈,其中stac为模拟用的栈,check为待检查的序列;
2,声明index指针指明当前遍历数组check的位置;
3,利用for循环,令i 从1 到 N+1,i与check[index]的关系分为两种:
i<=check[index]:此时将i存入stac中。(要注意,i=N时,仍会将i存入stac中,而此时模拟尚未结束,故 i 的上限为N+1;每向stac加入一个元素,就要判断一下stac是否以达到最大规模)
i>check[index]:将stac栈顶元素弹出,并且index++;
4,结束条件:当for循环结束后,若为出栈序列,那么此时stac应该为空;否则输出"NO";
3,代码
#include<iostream>
#include<vector>
#include<string.h>
#include<algorithm>
using namespace std;
int main(){
#ifdef ONLINE_JUDGE
#else
freopen("1.txt", "r", stdin);
#endif
int M, N, K; //M堆栈容量 N序列的长度 K需要检查的序列数目
scanf("%d %d %d", &M, &N, &K);
for(int i = 0; i < K; i++){ //K次
int num, back;
vector<int> stac, check; //stac用于模拟的栈 check需要检查的序列
for(int j = 0; j < N; j++){
scanf("%d", &num);
check.push_back(num);
}
int index = 0;
bool flag = true;
for(int k = 1; k <= N + 1 && flag == true; k++){ //k<=N+1,因为到N时还需要继续进行
if(k <= check[index]){
stac.push_back(k);
if(stac.size() > M){ //超出规定栈的大小
flag = false;
break;
}
}
while(stac.size() > 0 && stac[stac.size()-1] == check[index]){
stac.pop_back();
index++;
}
}
if(stac.size() > 0) flag = false;
if(flag == true) printf("YES\n");
else printf("NO\n");
}
return 0;
}