//题意:简单来说就是给你一个值n,然后给你一个n个数字的序列满足递增关系,让你判断是否满足栈的后进先出原则,然后题目输出和输入注意一下
//思路:对于此题,给定你序列的出栈顺序,那么首先考虑的是栈的出栈方式有两种,1.要么进栈后直接出栈;2.要么进栈后此时当前元素为栈底元素;那么基于这个思路有两个操作1)首先从最小的元素也就是1开始判断是否为给定顺序的第一个元素,也就是是否为第一种出战方式,若是则继续判断下一个元素递增元素,若不是第一种方式则采用第二种方式即接下来的操作;2)因为给定顺序的首元素与当前递增元素的值不同那么,push到一个栈中即可;所以实际只需要不断重复上面两步即可,但是1)是否有必要性呢?回答肯定是有的,这一步旨在判断当前元素,是否能匹配到给定序列的头元素,若不能匹配压栈,但主要是若能匹配的话此时当前元素更新,序列头元素也更新,我们需要首先判断当前元素是否匹配序列头元素,不匹配时再判断栈内元素执行3)所以1)和3)从逻辑上是两种出栈方式导致的结果可以看作2)导致3)这个结果,则1)是第一种出栈方式;2)和3)是第二种出栈放式,固1)是必要的.
//总结:简单来说因为两种出栈方式则有两种判断方式:1. 1)直接进出栈方式;2. 由3)导致的2)这种进栈即当作栈底元素的这种方式,可能表达不是很好,但主要就是有两种不同方式而形成的不同的判断方式。【注意】感谢看到提出疑问的朋友,这里又重新对其进行了修改,希望看到问题的朋友指出然后我们一起进步谢谢。
#include <iostream>
#include <stack>
using namespace std;
const int len = 1024;
int prior[len];
int main() {
int n;
while (cin >> n && n) {
stack<int> s;
while (cin >> prior[0] && prior[0]) {
for (int i = 1; i < n; i++) {
cin >> prior[i];
}
int j = 0, a = 1;
bool ok = true;
while (j < n) {
if (a == prior[j]) { //1)
a++;j++;
}else if(!s.empty() && s.top() == prior[j]) { //3)
s.pop();j++;
}else if(a <= n){ //2)
s.push(a++);
}else {
ok = false;
break;
}
}
cout << (ok ? "Yes" : "No") << endl;
}
cout << endl;
}
return 0;
}