小H很喜欢吃糖。
有一天,小L给小H准备了一大串糖果,它们从前往后排成一行,每个糖果上都写有一个小写字母。由于单纯的吃糖显得太单调,于是小L制定了一个规则,小H只能选择一个糖果,然后依次吃掉它和它后面的所有糖果。吃掉的这串糖果的组成的字符串字典序越大,小H的满意度就越高。然而小H可不会这么轻易地就同意小L的规则,于是据理力争来了一个条件:可以任意选择恰好一个位置,将上面的糖果替换为写有任意一个小写字母的糖果(允许替换前后的糖果上的字母相同)。
现在,聪明的你告诉小H,该如何替换糖果以及选择起始位置的糖果,得以让小H的满意度最高呢?
对于两个字符串 s1𝑠1 和 s2𝑠2,它们的长度分别为 n1𝑛1 和 n2𝑛2。定义 s1𝑠1 的字典序比 s2𝑠2 的小,当且仅当其满足以下两个条件之一:
- 如果存在一个位置 i𝑖,使得对于所有 j<i𝑗<𝑖,s1,j=s2,j𝑠1,𝑗=𝑠2,𝑗,而 s1,i<s2,i𝑠1,𝑖<𝑠2,𝑖。即在第一个不相等的位置上,s1𝑠1 的字母在字母表中的顺序靠前。
- 如果 s1𝑠1 是 s2𝑠2 的前缀,且 n1<n2𝑛1<𝑛2。
Input
第一行输入一个 n𝑛 (1≤n≤50001≤𝑛≤5000) ,代表糖果的个数。
第二行输入一个字符串 s𝑠 (|s|=n|𝑠|=𝑛) ,代表糖果上字母的序列。
题目保证 s𝑠 只包含小写字母。
Output
输出共一行一个字符串,表示让小H满意度最大的糖果串。
Examples
Inputcopy | Outputcopy |
---|---|
10 | zzzzzzabcd |
zzazzzabcd |
Inputcopy | Outputcopy |
---|---|
8 | zzzzbcd |
azzzabcd |
题解
观察题目易知把某个非z的字符更改为z一定是最优的策略,利用最大子段和思想,在截取字段和的过程中,在进一步将该段字符串的第一个非Z的元素与当前最大值进行比较,求出最终的最大字符串。
#include<iostream>
#include<string>
using namespace std;
int main()
{
int n;
string s,h;//两个空字符串
cin>>n>>s;
for(int i=0;i<s.size();i++)
{
string d;
int f=0;
for(int j=i;j<s.size();j++)
{
d+=s[j];
if(d[d.size()-1]!='z'&&f==0)//判断第一个不为z的位置,也就是每次相加后最后一个字母
{
d[d.size()-1]='z';
f=1;//用f来标记已经变更过
}
}
if(i!=0)
{
if(d>h)//将每次取得的字符串与最大相比较
h=d;
}
else
h=d;
}
cout<<h;
}