题目链接:https://codeforces.com/contest/1493/problem/C
题目大意:输入两个数,和一个长度为的字符串,只包含小写字母。
定义一个字符串为“好串”:字符串中每个字符出现的次数均为的整数倍。
求出一个长度为,只包含小写字母的字符串,这个字符串为一个好串,且字典序不小于字符串,且为所有满足上述条件的字符串中字典序最小的字符串。
题解:若不为的整数倍,则一定无解。
若字符串本身是一个好串,则答案就为字符串。
剩余的情况,我们求出答案字符串与字符串的最长相同前缀长度。
我们可以枚举相同前缀长度,在前位相同的情况下,我们再枚举第位的字符
接下来,对于已经填入的字符,计算出总共还需要多少字符才能让前面的字符满足数量条件,记为。
若,则当前情况不能构造出满足条件的解。
若,则我们先填个字母,再从字典序小的字母开始填入需要填入的字符。
我们可以维护,所以复杂度为,为小写字母的个数。
详情见代码:
#include<bits/stdc++.h>
using namespace std;
const int nn =510000;
const int inff = 0x3fffffff;
const double eps = 1e-8;
typedef long long LL;
const double pi = acos(-1.0);
const LL mod = (479 << 21) + 1;
int n,k;
string s;
int cnt[30];
int calc(int i)
{
return (k-i%k)%k;
}
int main()
{
int t;
cin>>t;
while(t--)
{
cin>>n>>k;
cin>>s;
if(n%k!=0)
{
cout<<-1<<endl;
continue;
}
memset(cnt,0,sizeof(cnt));
for(int i=0;i<n;i++)
cnt[s[i]-'a']++;
int sum=0;
for(int i=0;i<26;i++)
sum+=calc(cnt[i]);
if(sum==0)
{
cout<<s<<endl;
continue;
}
bool ans=false;
for(int i=n-1;i>=0;i--)
{
sum-=calc(cnt[s[i]-'a']);
cnt[s[i]-'a']--;
sum+=calc(cnt[s[i]-'a']);
for(int j=s[i]-'a'+1;j<='z'-'a';j++)
{
int lastsum = sum;
sum-=calc(cnt[j]);
cnt[j]++;
sum+=calc(cnt[j]);
if(i+sum+1<=n)
{
for(int index=0;index<i;index++)
cout<<s[index];
cout<<char(j+'a');
for(int index=0;index<n-sum-i-1;index++)
{
cout<<'a';
}
for(int index=0;index<26;index++)
{
int num=calc(cnt[index]);
while(num--)
{
cout<<char('a'+index);
}
}
cout<<endl;
ans=true;
break;
}
cnt[j]--;
sum = lastsum;
}
if(ans)
break;
}
}
return 0;
}