题目链接:http://codeforces.com/problemset/problem/797/C
题意:
给你一个非空字符串s,空字符串t和u。有两种操作:(1)把s的首字符取出并添加到t的末尾。(2)把t的尾字符取出并添加到u的末尾。
问你当经过一系列操作后,s和t均为空时,字典序最小的u。
题解:
操作的本质:
s为队列,t为栈。
贪心思路:
(1)找到s中的最小字符c,不断出队并加入t,直至有一次出队的字符等于c,停止出队。
(2)当t的尾字符小于等于s中的最小字符时,优先弹出t的尾字符,加入答案u。
模拟:
s和t分别用队列和栈实现。
另外,由于贪心过程中每次都要查询s中的最小字符,所以要开一个multiset,存储s中的字符。每次q.pop()之前,先将multiset中的一个值为q.front()的元素删除。
注:multiset中的erase(c)函数,会将multiset中所有值为c的元素都删除。。。
所以要这样:multiset<char>::iterator it = mst.find(c); mst.erase(it);
AC Code:
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stack>
#include <queue>
#include <set> using namespace std; string s;
string ans;
multiset<char> mst;
queue<char> q;
stack<char> stk; void read()
{
cin>>s;
for(int i=;i<s.size();i++)
{
q.push(s[i]);
mst.insert(s[i]);
}
} void solve()
{
while(!(q.empty() && stk.empty()))
{
while(!stk.empty() && (q.empty() || stk.top()<=*mst.begin()))
{
ans+=stk.top();
stk.pop();
}
if(!q.empty())
{
char c=*mst.begin();
while()
{
bool flag=false;
if(q.front()==c) flag=true;
stk.push(q.front());
multiset<char>::iterator it=mst.find(q.front());
mst.erase(it);
q.pop();
if(flag) break;
}
}
}
} void print()
{
cout<<ans<<endl;
} int main()
{
read();
solve();
print();
}