题目链接:http://poj.org/problem?id=1363 (lrj白书习题)
题目大意:判断一个出栈序列能不能从1,2,3,……,n 经过栈处理后生成。
思路:
Ⅰ:定理:出栈序列不合法 <=> 存在k,满足i<j<k,使得S[k]<S[i]<S[j]。(i,j,k是入站顺序,s[i],s[j],s[k]是出栈顺序)。
如果用这个定理判断则需要O(n^3)的时间,不合适。
Ⅱ:模拟即可:模拟入栈,①如果当前要进栈的元素是下一个要出栈元素则直接让他入栈出栈就行了,跳到下一个。
②如果当前栈顶元素是下一个要出栈元素则让它出栈。
③否则把当前元素进栈来看下一个
当要进栈的所有元素都处理后,依次弹出栈内元素,如果有和出栈元素不符的则出栈序列不合法。
#include <iostream> #include <cstdio> #include <cstring> #include <stack> using namespace std; int s[1010]; int main(){ //freopen("data.txt","r+",stdin); int n; while(cin>>n){ if (n == 0) break; while(cin>>s[0]){ stack <int> t; //memset(s,0,sizeof(s)); if (s[0] == 0){ break; } for (int i = 1; i < n; i ++){ cin>>s[i]; } int b = 0; int i = 0; while (i < n){ if (i + 1 == s[b]){ b ++; i ++; } else if (!t.empty() && t.top() == s[b]){ t.pop(); b ++; } else{ t.push(i + 1); i ++; } } int ok = 1; while(!t.empty() && b < n){ if (t.top() != s[b]){ ok = 0; break; } t.pop(); b ++; } if (ok) cout<<"Yes\n"; else cout<<"No\n"; } cout<<endl; } return 0; }