題目連結: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 }