题目描述
给定一个长度为
n
n
n的、仅由小写字母组成的字符串,将其按序依次放入栈中。
请问在所有可能的出栈序列中,字典序最小的出栈序列是多少?
输入格式
输入第一行, 一个正整数
n
n
n
输入第二行,一个长度为
n
n
n的字符串
输出格式
输出所有出栈序列中,字典序最小的出栈序列
数据范围
对于30%的数据,
1
≤
n
≤
10
1≤n≤10
1≤n≤10
对于60%的数据,
1
≤
n
≤
1
0
3
1≤n≤10^3
1≤n≤103
对于100%的数据,
1
≤
n
≤
1
0
5
1≤n≤10^5
1≤n≤105
样例数据
输入:
3
yes
输出:
esy
说明:
字符y、e、s依次进栈,所有出栈的可能性有:{yes}、{yse}、{eys}、{esy}、{sey} 其中 {esy} 的字典序最小
分析
思路一:
背景:会搜索的同学窃喜
可以利用搜索配合栈来搜出最优解。
代码:略
思路二:
背景:想想,当前你栈里有一个y,还有e,s要进栈,那y是出栈还是保留?
从样例来看是保留
why?
可以在入栈的e,s入手,发现e的字典序小于y的字典序
那么y显而易见要保留
可如果要进栈的字典序全大于y的字典序呢?
那y就是最小的,出栈!!
可进栈的字典序都和y的字典序一样呢?
反正得要保留一个,那肯定是出栈啦!!!!
利用一个新生没学过的技巧:葵花宝典最小后缀和,再搭配STL中的栈,就行了,不懂得STL栈的可以去看这里:
这是我自己写的,觉得不行就去网上找关于栈的文章
最后填上代码:
#include <bits/stdc++.h>
using namespace std;
const long long MAXN=1e5+10;
string st;
int n,x=0;
char a[MAXN];
int main(){
cin>>n>>st;
a[n-1]=st[n-1];
for(int i=n-2;i>=0;--i){
a[i]=min(st[i],a[i+1]);
}
stack <char> s;
while(s.empty()!=true||x<n){
if(s.empty()==true||x<n&&a[x]<s.top()){
s.push(st[x++]);
}
else{
cout<< s.top();
s.pop();
}
}
return 0;
}