C. K-beautiful Strings
https://codeforces.com/contest/1493/problem/C
给定一个字符串,让你重新构造出一个和他等长的字符串,并且每个单词出现次数都是k的倍数。
思路:
从后往前贪心,我们枚举每个要第一次修改的点k,然后让1k-1都不相等,记录1k-1每个单词需要补的次数,然后从小到大枚举该位要修改的单词,并且更改cnt,然后sum=需要修改的值,如果sum+目前的位数(位数>=1)小于等于该字符串,就说明可以了。剩下的位置都填a就行了,有个疑问,剩下的位置为什么%k==0呢?其实蛮明显的,因为sum%k==0 && n%k==0 所以(n-sum)%k==0
#include<bits/stdc++.h>
#define IL inline
#define x first
#define y second
typedef long long ll;
using namespace std;
string s;
int cnt[27]; int n,k;
int get(int x)
{
return (k-(x%k))%k;
}
int main()
{
int t;
cin>>t;
while(t--)
{
cin>>n>>k;
cin>>s;
memset(cnt,0,sizeof cnt);
for(int i=0;i<s.size();i++)
cnt[s[i]-'a'] ++;
int res=0;
for(int i=0;i<=25;i++)
res+=get(cnt[i]);
int sum=res;
if(res==0) cout<<s<<endl;
else if(n%k) cout<<-1<<endl;
else
{
for(int i=n-1;i>=0;i--)
{
sum=sum-get(cnt[s[i]-'a'])+get(--cnt[s[i]-'a']);
bool flag=0;
for(int j=s[i]-'a'+1;j<=25;j++)
{
int lst=sum;
sum=sum-get(cnt[j])+get(++cnt[j]);
if(i+1+sum<=n)
{
int tt=n-(i+1+sum);
flag=1;
for(int k=0;k<i;k++)
cout<<s[k];
cout<<(char)(j+'a');
while(tt--) cout<<'a';
for(int k=0;k<=25;k++)
{
int kk=get(cnt[k]);
while(kk--)
cout<<(char)(k+'a');
}
cout<<endl;
break;
}
sum=lst;
cnt[j]--;
}
// cnt[s[i]-'a']++;
if(flag)
break;
}
}
}
return 0;
}