C.フェニックスと流通
CF1348 C
質問の意味:与えられた文字列s、その中の各文字はkkに分割する必要がありますk空でない文字列。すべてのサブメソッドで最大の辞書編集文字列の最小値を出力する必要があります。
アイデア:
まず、それが空でないことを確認してください。最小数の文字がkを埋められない場合は、ソート後にk番目の文字を直接出力します。(残りのすべての文字は、最小の文字の後に配置できます)
次に、均等に分割考えは行きます:
- 残りのすべての値が同じ場合、最長の値が均等に分割されます。
- 同じでない場合は、残りの文字を辞書式順序で最小から最大まで出力します。
int vis[30],v[30];
int n,m,a,b,co=0,nw,tn,fla;
char tt;
int ju(){
fla=1;
if(co==1||(vis[v[1]]==0&&co==2)){
tt='a'+v[1];cout<<tt;
for(int i=1;i<=co;i++){
for(int j=1;j<=vis[v[i]]/m+(vis[v[i]]%m!=0);j++){
tt='a'+v[i];cout<<tt;}
}
cout<<endl;
}
else fla=0;
return fla;
}
int main(){
int t;
cin>>t;
string s;
while(t--){
mem(vis,0);
co=0;
cin>>n>>m>>s;
for(int i=0;i<n;i++){
if(vis[s[i]-'a']==0){
v[++co]=s[i]-'a';
}
vis[s[i]-'a']++;
}
sort(v+1,v+1+co);
if(vis[v[1]]>=m){
vis[v[1]]-=m;
if(ju()==1)continue;
tt='a'+v[1];cout<<tt;
nw=1;
if(vis[v[nw]]==0)nw++;
for(int i=1;i<=n-m;i++){
tt='a'+v[nw];cout<<tt;
vis[v[nw]]--;
if(vis[v[nw]]==0){
nw++;}
}
cout<<endl;
continue;
}
else{
nw=0;fla=1;
for(int i=1;;i++){
if(nw+vis[v[fla]]>=m){
tt='a'+v[fla];cout<<tt<<endl;
break;
}
nw+=vis[v[fla++]];
}
}
}
}