P1155 双栈排序
题目大意:
通过两个栈,四种操作,实现一个输入序列的升序排序
操作a: 如果输入序列不为空,将第一个元素压入栈
操作b: 如果栈
操作c: 如果输入序列不为空,将第一个元素压入栈
操作d: 如果栈
要求输出一个字符串,即操作顺序。若有多种操作,输出字典序最小的情况;若输入序列无法进行双栈排序,则输出0
思路:
通过贪心的思路可以很快的解答这个问题。
由于要求输出字典序最小的情况,所以操作应该遵循 “
代码:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<stack>
using namespace std;
stack<int> s1,s2;
int n,a[1005],cur=1,l=1;
//cur是现在需要的数
//l相当于一个指针,用于调用目前没有处理的数中最前面的数
string output;
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
//因为要输出最小字典序的结果,所以所有的操作都是s1优先于s2
while(cur<=n){
if(!s1.empty()&&s1.top()==cur){
//若s1顶为所需数,弹出
s1.pop();
output+="b ";
cur++;
}
else if(!s2.empty()&&s2.top()==cur){
//若s2顶为所需数,弹出
s2.pop();
output+="d ";
cur++;
}
else if(a[l]==cur){
//若待当前为所需数,则压入s1后立即弹出
output+="a b ";
cur++,l++;
}
else if(!s1.empty()&&s1.top()==a[l]+1){
//若s1顶为下一个所需数,则将当前数压入s1
s1.push(a[l]);
output+="a ";
l++;
}
else if(!s2.empty()&&s2.top()==a[l]+1){
//若s2顶为下一个所需数,则将当前数压入s2
s2.push(a[l]);
output+="c ";
l++;
}
else if(s1.empty()||s1.top()>a[l]){
//若s1为空或s1顶大于待当前数,则将当前数压入s1
s1.push(a[l]);
output+="a ";
l++;
}
else if(s2.empty()||s2.top()>a[l]){
//若s2为空或s2顶大于待当前数,则将当前数压入s2
s2.push(a[l]);
output+="c ";
l++;
}
else{
//若以上所有操作都无法进行,则无法进行双栈排序
printf("0\n");
return 0;
}
}
cout<<output<<endl;
return 0;
}