题目连接:Problem - 1675E - Codeforces
理解题目:输入一个字符串,将此字符串中相同的字母同时进行递减,问k次递减后,此字符串的最小字典序(查字典的字母排列顺序)eg:cba——bba——aaa共消耗了2步,第一步将c变成b,第二步将两个相同的b同时变成a。
解题思路:1.既然是要转换为字典顺序最小的字符串,那应该最先考虑下标小的字符,就是越靠前的字符就应该越小
2.题目的操作其实就是对于某个字母x,要将它变成a,那么它必须满足x-a<=k,执行次数不超过k,才可以将x变成a,那么比x小的字符也都可以通过最多不超过x-a的执行次数变成a,即在[a,x]范围内的字符都可以变成a
代码展示:
#include <stdio.h>
int main()
{
int t,n,k,maxcount=0,count;
int i,j,max,min;
char s[200001];
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&k);
getchar();//下面用的是gets,上文输入后按回车会被gets吸收,所以要用一个getchar吃掉
gets(s);
maxcount=0;
for(i=0;i<n;i++)
{
count=s[i]-'a';
if(count<=k)
maxcount=maxcount>count?maxcount:count;//当减去k可以到a时,记下可减去最大的那个数
else
{ //如果第一个字母减去k不能直接到a,就重新设定范围[x-(k-maxcount),x]
min=s[i]-(k-maxcount);//因为到这里时要用到剩下的k
max=s[i];
for(j=i;j<n;j++)
if(s[j]>=min&&s[j]<=max)
s[j]=min;
break;
}
}
for(i=0;i<n;i++)
{
if(s[i]-'a'<=maxcount)//让每一个在[a,s[0]]范围内的字母直接变成a
s[i]='a';
}
puts(s);
/*for(i=0;i<n;i++)
if(k>=maxcount&&s[i]<=s[0])//这种情况当输入cba时会输出aba
s[i]='a'; //因为此时的s[0]变化了,变成了a
puts(s);*/
}
return 0;
}