题目大意
给我们一个字符串s,我们需要找到一个字符串str,满足str的字典序大于s并且str中每个字母的数量要能被k整除
题解
首先判断一定不存在的情况,n无法被k整除,这种情况直接输出-1,其他情况,我们可以先遍历字符串,得到所有字符的数量,并且计算每个字符需要再增加多少个字符才能被k整除,然后从后往前遍历字符串,尝使将选中的字符改为比其大的字符后计算还需要多少字符可以被k整除,如果选中了第i个字符,并且所需的字符小于n-i,证明我们可以修改i后面的字符,使得所有字符的数量可以被k整除,因为n可以被k整除,所以就算所需字符不是正好达到n-i,那多余的字符空位也可以用a来填充,并且填充的数量一定被k整除,上代码
#include<cstdio>
#define MAX 100005
int cnt[30];
char str[MAX];
int get(int x,int k){
return (k-x%k)%k;
}
int main(){
int T,k,n,sum,las,flag;
scanf("%d",&T);
while(T--){
flag=1;
sum=0;
for(int i=0;i<26;i++){
cnt[i]=0;
}
scanf("%d%d",&n,&k);
scanf("%s",str);
for(int i=0;str[i];i++){
cnt[str[i]-'a']++;
}
for(int i=0;i<26;i++){
sum+=get(cnt[i],k);
}
if(!sum){
printf("%s\n",str);
}else if(n%k){
printf("-1\n");
}else{
for(int i=n-1;i>=0;i--){
sum=sum-get(cnt[str[i]-'a'],k)+get(--cnt[str[i]-'a'],k);
for(int j=str[i]-'a'+1;j<26;j++){
las=sum;
sum=sum-get(cnt[j],k)+get(++cnt[j],k);
if(i+sum+1<=n){
for(int pr=0;pr<i;pr++){
printf("%c",str[pr]);
}
printf("%c",j+'a');
for(int pr=0;pr<n-sum-(i+1);pr++){
printf("%c",'a');
}
for(int pr=0;pr<26;pr++){
int prf=get(cnt[pr],k);
for(prf;prf>0;prf--){
printf("%c",'a'+pr);
}
}
printf("\n");
flag=0;
break;
}
sum=las;
cnt[j]--;
}
if(!flag){
break;
}
}
}
}
return 0;
}
如果描述不清或者有误,欢迎大佬指正