传送门:牛客
题目翻译(详细见原文):
输出一串长度为n的全排列,问你能否用顺序为1,2,3,4...n的进栈顺序完成此操作(在任何
时候都能出栈)
输入:
5
1 2 3 4 5
5 4 1 2 3
0
6
6 5 4 3 2 1
0
0
输出:
Yes
No
Yes
主要思路:我们先枚举给定的全排列,因为栈的规则是先进后出的原则,并且进栈是逐步进栈的,所以若当前我们的栈的顶端没有枚举到的数字,意味着要不是这个全排列是不能完成的,要不就是数字在后面,还没有进栈,因此我们此时继续进栈,然后继续看是不是符合,不然就继续进栈
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <string.h>
#include <stack>
using namespace std;
typedef long long ll;
#define inf 0x3f3f3f3f
#define root 1,n,1
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
inline ll read() {
ll x = 0, w = 1;
char ch = getchar();
for (; ch > '9' || ch < '0'; ch = getchar()) if (ch == '-') w = -1;
for (; ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';
return x * w;
}
#define maxn 1000000
stack <int>num;
int main() {
int n;
while (cin >> n && n != 0) {
while (1) {
//每一次都要情况我们的栈
while (!num.empty()) num.pop();
int a;
//flag代表是不是0,因为输入格式的原因
int flag = 1;
int res = 1;
int ans = 0;
//因为1是第一个,这是必须要进栈的,我们先进栈
num.push(res);
for (int i = 1; i <= n; i++) {
a = read();
if (a == 0) {
flag = 0;
break;
}
//开始枚举不断进栈直到符合的数字进栈
while (num.top() != a) {
num.push(++res);
//如果直到最后也不行,说明这个数字在底部,也就说明不可能完成
if (res > n) {
ans = 1;
break;
}
}
num.pop();
//这一步细节很重要,因为我们不断的pop,栈中迟早是会空的,因此我们需要判断一下长度
if (num.size() == 0) num.push(++res);
}
if (flag == 0) break;
if (ans == 0) cout << "Yes" << endl;
else cout << "No" << endl;
}
cout << endl;
}
return 0;
}
做题时的错误:
当时做题时将empty();函数当成清空函数了,然后找了很久bug总是不对,最离谱
的是样例居然是正确的,然后是在没办法造了一个对拍数据对拍了一下,终于找到了没有情况,查了一下才发现,这个函数只是用来判断栈是不是为空??,焯,我就想问那你的size()函数有什么用??然后stack是没有清空函数的…,需要手动清空