題意:
給出了字符串s的內容,字符串t,u初始默認為空,允許做兩種操作:
1、把s字符串第一個字符轉移到t字符串最后
2、把t字符串最后一個字符轉移到u字符串最后
最后要求s、t字符串都為空,問u字符串字典序最小能是多少。
解題關鍵:
主要就是貪心,按字典序,每貪心完一個字母,往前回溯一次。
1、hash一下每個字母出現的次數,然后貪心選擇字典序最小的即可。
2、預處理每個位置能達到的最小的字母,然后貪心。tmp一定是一個單調不減的數組。
3、小于等于而不是等于的原因是abacd這種情況。
反思:
1、這種看似簡單的模擬題一定要搞明白,自己寫一下。類似于棧混洗。
2、string的這種類似java和python的用法
法1:
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 stack<char>s1; 5 int m1[300]; 6 int cnt=0; 7 char s2[100020]; 8 int main(){ 9 string s; 10 int nn=0; 11 cin>>s; 12 for(int i=0;s[i];i++) m1[s[i]-'a']++; 13 while(!m1[nn]&&nn<26)nn++; 14 for(int i=0;s[i];i++){ 15 if(s1.empty()||m1[nn]){ 16 s1.push(s[i]); 17 m1[s[i]-'a']--; 18 } 19 while(!s1.empty()&&s1.top()<=nn+'a'){//改成小于等于就過了 20 s2[cnt++]=s1.top(),s1.pop(); 21 while(!m1[nn]&&nn<26)nn++; 22 } 23 while(!m1[nn]&&nn<26)nn++; 24 } 25 while(!s1.empty()) s2[cnt++]=s1.top(),s1.pop(); 26 printf("%s\n",s2); 27 }
法二:
1 #include<bits/stdc++.h> 2 #define inf 0x3f3f3f3f 3 using namespace std; 4 typedef long long ll; 5 stack<char>ss; 6 char tmp[100010],x; 7 int main(){ 8 string s; 9 cin>>s; 10 x='z'+5; 11 for(int i=s.size()-1;i>=0;i--) x=min(x,s[i]),tmp[i]=x;//tmp[i]代表該位置能使結果到達最小的值 12 string ans=""; 13 for(int i=0;i<s.size();i++){ 14 while(!ss.empty()&&ss.top()<=tmp[i]) ans+=ss.top(),ss.pop(); 15 ss.push(s[i]); 16 } 17 while(!ss.empty()) ans+=ss.top(),ss.pop(); 18 cout<<ans<<"\n"; 19 return 0; 20 }
?