题意:
给出了字符串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 #include2 using namespace std; 3 typedef long long ll; 4 stack 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 #include2 #define inf 0x3f3f3f3f 3 using namespace std; 4 typedef long long ll; 5 stack 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