题目:
输入
N= 6
s = "ACDBCB"
输出
ABCBCD(如下图所示进行操作)
分析:
从字典序的性质上看,无论T的末尾有多大,只要前面部分的较小就可以。所以我们可以试一下如下贪心算法:
■不断取S的开头和末尾中较小的一一个字符放 到T的末尾。
这个算法已经接近正确了,只是针对S的开头和末尾字符相同的情形还没有定义。在这种情形下,因为我们希望能够尽早使用更小的字符,所以就要比较下一个字符的大小。下一个字符也有可能相同,因此就有如下算法:
■按照字典序比较S和将S反转后的字符串S'。
■如果S较小,就从S的开头取出一-个文字, 追加到T的末尾。
■如果S较小,就从S的末尾取出一个文字,追加到T的末尾。
(如果相同则取哪个都可以)
根据前面提到的性质,字典序比较类的问题经常能用得上贪心法。
代码实现:
#include<iostream>
#include<string>
using namespace std;
int n;
string s;
void solve() {
string t="";
int l=0,r=n-1;
while(l <= r) {
bool left=false;
//左右子串分别比较大小
for(int i=0; i+l<r; ++i)
if(s[i+l]<s[r-i]) {
left=true;
break;
} else if(s[l+i]>s[r-i]) {
left=false;
break;
}
if(left)
t+=s[l++];
else t+=s[r--];
}
cout<<t;
}
int main() {
cin>>n;
cin>>s;
solve();
return 0;
}