总时间限制: 1000ms 内存限制: 65535kB
描述
依次读入序列元素1,2,...,n进栈,每进一个元素,机器可要求下一个元素进栈或弹栈,如此进行。给定一个输入序列,判断栈空时弹出的元素构成的序列是否可能等于给定的序列,如果是则输出栈的操作过程,否则输出“NO”。
输入
输入分两行
第一行为n的值(即序列元素个数)
第二行为给定的输入序列(序列元素均为整型)
输出
如果输入序列能够由题目规定的操作得到,则输出对栈的操作过程
否则直接输出“NO”
样例输入
7
4 5 3 6 2 7 1
样例输出
PUSH 1
PUSH 2
PUSH 3
PUSH 4
POP 4
PUSH 5
POP 5
POP 3
PUSH 6
POP 6
POP 2
PUSH 7
POP 7
POP 1
提示
给定序列中有可能有不在1...n之间的数字
AC代码
#include <bits/stdc++.h>
using namespace std;
int n;
deque<int> seq;
bool appeared[1000001] = {};
bool isLegal(deque<int> &seq) {
vector<int> pushV;
for (int i = 1; i <= n; i++) {
pushV.push_back(i);
}
if (pushV.size() != seq.size() || pushV.size() == 0 || pushV.size() == 0)
return false;
stack<int> stackData;
size_t pop_idx = 0;//
size_t idx = 0;
for (; idx < pushV.size(); idx++) {
stackData.push(pushV[idx]);
while (stackData.size() != 0 && stackData.top() == seq[pop_idx]) {
stackData.pop();
pop_idx++;
}
}
return stackData.empty() && idx == pop_idx;
}
int main() {
scanf("%d", &n);
int flag = 0, tmp;
for (int i = 0; i < n; i++) {
scanf("%d", &tmp);
if (tmp > n || tmp <= 0 || appeared[tmp])
flag = 1;
seq.push_back(tmp);
if (!flag)
appeared[tmp] = true;
}
if (flag || !isLegal(seq)) {
printf("NO");
return 0;
}
stack<int> sim;
int cnt = 1;
printf("PUSH %d
", cnt);
sim.push(cnt);
while (!seq.empty()) {
if (sim.empty() || seq.front() != sim.top()) {
cnt++;
printf("PUSH %d
", cnt);
sim.push(cnt);
} else {
printf("POP %d
", sim.top());
sim.pop();
seq.pop_front();
}
}
return 0;
}
单纯模拟