题目大意:给定长度为N的字符串S,要构造一个长度为N的字符串T。起初,T是一个空串,随后反复进行下列任意操作。
从S的头部删除一个字符,加到T的尾部
从S的尾部删除一个字符,加到T的尾部
目标是构造字典序尽可能小的字符串。
输入:
6
ACDBCB
输出
ABCBCD
解题思路:
这道题我们很容易想到,不断取开头或者结尾最小的一个字母放到T中就可以了。这个思路是正确的,不过我们要针对开头和结尾相同的情况来进行一下判断,便得到如下算法:
1.按照字典序比较S和将S反转后的字符串
2.如果S较小,就从S的开头取出一个字符
3.如果S’较小,就从S的末尾取出一个字符
AC代码:
#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
using namespace std;
const int N = 1e5+10;
char s[N+1];
int n;
void solve()
{
int a = 0;
int b = n-1;
while(a <= b)
{
int left = false;
for(int i = 0 ; a+i <= b ; i++)
{
if(s[a+i]<s[b-i])
{
left = true;
break;
}
else if(s[a+i]>s[b-i])
{
left = false;
break;
}
}
if(left)
putchar(s[a++]);
else
putchar(s[b--]);
}
putchar('\n');
}
int main()
{
cin >> n;
scanf("%s",s);
solve();
return 0;
}
所以说,字典序比较类的问题,经常能用的到贪心算法。