很简单的分类问题,给出一个长为n的字符串,分为k个字段,使k个子串中字典序最大的尽可能最小;
简单的方法就是将输入的n个字符重新排序,当s[0]!=s[k-1]时,证明当最小字典序的字符不可以作为所有k个子串的第一个字符,此时最大字典序最小的子串一定为s[k-1],s[0]==s[k-1]时,判断s[k]是否等于s[n-1],若相等,则将其后字符均分在k个子串,有余则加一,既(s[0],s[k]--s[(n-k)/k]为所求,若不相等,则(s[0],s[k]--s[n-1])为所求。
#include<iostream>
#include<map>
using namespace std;
int t,n,k;
int main()
{
cin>>t;
while(t--){
map<int,int> ma;
string s,s1;
cin>>n>>k;
cin>>s;
int maxn=0;
for(int i=0;i<n;i++){
ma[s[i]-'a']++;
}
int jj=0;
int flag=0;
for(int i=0;i<26;i++){
if(ma[i]!=0){
if(ma[i]>=k&&flag==0){
ma[i]-=k;
s1+=(i+'a');
for(int j=0;j<26;j++){
while(ma[j]!=0){
s1+=(j+'a');
ma[j]--;
}
}
break;
}
else{
flag=1;
// cout<<"J:"<<jj<<endl;
jj+=ma[i];
if(jj>=k){
s1+=(i+'a');
break;
}
}
}
}
// cout<<s1<<endl;
if(s1.size()>1){
char f=s1[1];
int flag=0;
for(int i=1;i<s1.size();i++){
if(s1[i]!=f){
flag=1;
break;
}
}
if(flag==0){
int l=s1.size();
l--;
if(l%k!=0){
l+=k;
}
l/=k;
cout<<s1[0];
for(int i=1;i<=l;i++){
cout<<s1[i];
}
cout<<endl;
}
else{
cout<<s1<<endl;
}
}
else{
cout<<s1<<endl;
}
}
return 0;
}
Null问题是:
当我把重复的字符段后半段等于NULL时,输出的应该是还占了一个字符位,所以一直wa1。