Codeforces Round #705 (Div. 2) C. K-beautiful Strings

传送门

题目大意

给我们一个字符串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;
}

如果描述不清或者有误,欢迎大佬指正

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值