Problem H
题意:给出n个字符.问把n个字符分成k个字符串 要求:这k个字符串的长度都相同,这k个字符串都为回文.
n<=4e5.求出最小的k 并输出这k个字符串.
k组字符串 每组中最多只能有一个出现奇数次的字符.
题意:给出n个字符.问把n个字符分成k个字符串 要求:这k个字符串的长度都相同,这k个字符串都为回文.
n<=4e5.求出最小的k 并输出这k个字符串.
k组字符串 每组中最多只能有一个出现奇数次的字符.
如何输出方案:先把g个奇数字符仍到每组中间,剩下的2个相同的一对,有c对 如果能平均分给每组 即c为g的倍数 则退出.否则拆掉一个偶数 增加组数后继续判定.O(127*|S|)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=4e5+5,M=125;
int n,g,fre[M];
vector<char> sing;
string s;
int calc()
{
int j=0;
while(true)
{
g=sing.size();
int c=(n-g)>>1;
if(c%g==0)//每组多少对.
return c;
while(j<M&& !fre[j])
j++;
fre[j]--;
sing.push_back(char(j));
sing.push_back(char(j));
}
}
int main()
{
memset(fre,0,sizeof(fre));
cin>>n>>s;
for(int i=0;i<n;i++)
fre[s[i]]++;
for(int i=0;i<M;i++)
{
if(fre[i]%2)
sing.push_back(char(i));
fre[i]/=2;
}
if(sing.size()==0)
{
cout<<1<<endl;
string B="";
for(int j=0;j<M;j++)
for(int k=0;k<fre[j];k++)
B+=char(j);
string C=B;
reverse(C.begin(),C.end());
B+=C;
printf("%s\n",B.c_str());
return 0;
}
int c=calc(),j=0;
cout<<g<<endl;
//for(int i=0;i<sing.size();i++)
// cout<<sing[i]<<' ';
for(int i=0;i<g;i++)
{
char x=sing[i];
int d=c/g;
string B="";
while(true)
{
while(j<M&& !fre[j]) j++;
if(fre[j]>=d)
{
for(int k=0;k<d;k++)
B+=char(j);
fre[j]-=d,d=0;
break;
}
else
{
for(int k=0;k<fre[j];k++)
B+=char(j);
d-=fre[j],fre[j]=0;
}
}
string C=B;
reverse(C.begin(),C.end());
B=B+x+C;
// cout<<B<<endl;
printf("%s ",B.c_str());
}
return 0;
}