NEERC 17 H. Palindromic Cut 暴力(回文)

来源:互联网 发布:网络棋牌交流群 编辑:程序博客网 时间:2024/06/14 14:04
Problem H
题意:给出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;}


原创粉丝点击