Codeforces 797C Minimal string:貪心+模擬

Leohh發表於2017-08-16

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

 

 

相關文章