【题目】http://codeforces.com/problemset/problem/797/C
【题意】有一个字符串s,和两个一开始为空的串t,r。有两种操作:1:将s的第一个移到t的最后;2:将t的第一个移到r的最后。
要求最后将所有字符移动到r中,并使r的字典序尽可能小。
【思路】我们看到,t的作用相当于一个栈。我们要使r的字典序最小,每次就要取到s中最小的字符放进r中,s在这个字符之前的所有字符全都放进t中。当然如果t栈顶又是最小的,那么就将这个字符输出。
所以,我们记录所有字符出现的次数,遍历整个s,每次取出一个字符x,cnt[x]--,把x放进栈里,判断小于x的字符的cnt是不是都==0,如果都为0的话,x就是最小的字符,那么将这个字符输出并pop。如果栈顶变化了就要循环判断栈顶是不是最小的字符。遍历完后,将栈里的元素输出。
【代码】
#include<bits/stdc++.h>
#define fuck(x) std::cout<<"["<<#x<<"->"<<x<<"]"<<endl;
using namespace std;
typedef long long ll;
const int M=1e5+5;
const int inf=1e9+5;
char a[M];
int cnt[30]={0};
stack<char>s;
int main()
{
scanf("%s",a);
int n=strlen(a);
for(int i=0;i<n;i++)//统计出现次数
cnt[a[i]-'a']++;
for(int i=0;i<n;i++)//遍历s
{
s.push(a[i]);
cnt[a[i]-'a']--;
while(!s.empty())
{
int flag=0;
for(char j='a';j<s.top();j++)
//当小于栈顶元素的字符都遍历过了,栈顶元素就是最小的
{
if(cnt[j-'a']!=0)
{
flag=1;
break;
}
}
if(flag==0)
{
printf("%c",s.top());
s.pop();
}
else break;
}
}
while(!s.empty())
{
printf("%c",s.top());
s.pop();
}
return 0;
}