Codeforces 797C Minimal string:贪心+模拟
题目链接: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:
1 #include <iostream> 2 #include <stdio.h> 3 #include <string.h> 4 #include <stack> 5 #include <queue> 6 #include <set> 7 8 using namespace std; 9 10 string s; 11 string ans; 12 multiset<char> mst; 13 queue<char> q; 14 stack<char> stk; 15 16 void read() 17 { 18 cin>>s; 19 for(int i=0;i<s.size();i++) 20 { 21 q.push(s[i]); 22 mst.insert(s[i]); 23 } 24 } 25 26 void solve() 27 { 28 while(!(q.empty() && stk.empty())) 29 { 30 while(!stk.empty() && (q.empty() || stk.top()<=*mst.begin())) 31 { 32 ans+=stk.top(); 33 stk.pop(); 34 } 35 if(!q.empty()) 36 { 37 char c=*mst.begin(); 38 while(1) 39 { 40 bool flag=false; 41 if(q.front()==c) flag=true; 42 stk.push(q.front()); 43 multiset<char>::iterator it=mst.find(q.front()); 44 mst.erase(it); 45 q.pop(); 46 if(flag) break; 47 } 48 } 49 } 50 } 51 52 void print() 53 { 54 cout<<ans<<endl; 55 } 56 57 int main() 58 { 59 read(); 60 solve(); 61 print(); 62 }