题目如下:

题目思路:
分两种情况:
操作数大于字母数,直接全部从小到大排序。
操作数小于字母数:
从第一个字母开始,如果当前第i个字母小于第i+1字母,把字符串往前移动,同时
,操作数k--,并记录哪个字母;
最后先输出操作后的字符串,然后再对操作过的字符从大到小进行输出就好。
!应该考虑一种情况,就是如果i到了最后,应该与操作过的最大字符相比,重复上面的操作。(因为这个一直wa)
代码如下(没有用到C++,码风怪异)
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
// static char * mystrcpy(char *dest, const char *src)
// {
// assert(dest != NULL && src != NULL);
// char *ret = dest;
// while ((*dest++ = *src++) != '\0');
// return ret;
// }
char arr[123456];
char narr[123456];
int alp[27];//
int kalp[27];
int main()
{
int i,n,k,j;
scanf("%d%d",&n,&k);//输入n,k
scanf("%s",arr);//输入字符串
// arr[n]=0;
for(i=0;i<n;i++)
{
alp[arr[i]-'a']++;//统计字母个数
}
if(k>=n)//如果操作次数不小于长度
{
for(i=25;i+1;i--)//从大往小直接输出
{
for(j=1;j<=alp[i];j++)
{
printf("%c",i+'a');
}
}
}
else//如果操作次数小于长度
{
int max=0,l,op=k;//l为操作位置
l=0;//设为0
while(op>0&&arr[l]!=0)//如果还有操作次数同时第l个字符后面还有字符
{
if(arr[l]<arr[l+1])//如果当前字符小于后面的字符
{
char temp[123456];
kalp[arr[l]-'a']++;//操作的字母对应个数+1
if(arr[l]-'a'>max) max=arr[l]-'a';
// for(i=l;arr[i];i++)
// {
// arr[i]=arr[i+1];
// }
strcpy(temp,&arr[l+1]);
strcpy(&arr[l],temp);
// strcpy(&arr[l],&arr[l+1]);//将字符串往前移动1位
if(l>0) l--;//如果l大于0,可以往后移动
op--;//操作次数减少1
}
else l++;//往前移动
if(!arr[l]&&op)
{
if(arr[l-1]-'a'<max)
{
kalp[arr[l-1]-'a']++;
arr[l-1]=0;
l--;
if(l>0) l--;
}
else break;
}
}
printf("%s",arr);//输出操作后的字符串
for(i=25;i+1;i--)//从大到小输出被操作的字符
{
for(j=1;j<=kalp[i];j++)
{
printf("%c",i+'a');
}
}
}
}
该文章描述了一种针对字符串的算法,根据操作数与字母数的关系进行不同策略的排序。当操作数大于字母数时,直接按字母顺序排序;否则,通过比较和移动字符来优化字符串。在处理过程中,特别注意了边界条件和字符比较的情况。
3152

被折叠的 条评论
为什么被折叠?



