CF883H

Posted repulser

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF883H相关的知识,希望对你有一定的参考价值。

CF883H

题意:

给你一个字符串,需要把它以最小的划分次数划分为x个长度相等的回文串,可以重新排列。

解法:

大模拟一个。
分别统计出现一次的字符和出现两次的字符,如果没有出现一次的字符,那么所有字符出现次数均为偶数,说明本身便可以排列成回文串。
如果某个字符出现次数为偶次,可以拆分为多个 $ \fraccnt2 $ 个相同字符存入,如果出现次数为奇数次,则先存入单个统计并计数减1,再存入双个统计,如果单个字符数量不足,则需要用双个字符填充。

CODE:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std; 

const int N = 4e5 + 100; 
char a[N],cnt[N * 2],s[N]; 
int Hash[300],n;

int main() 
    scanf("%d",&n);
    scanf("%s",s+1);
    for(int i = 1 ; i <= n ; i++)
        Hash[s[i]]++; 
    int L = 1, R = n; 
    for (int i = 1; i <= 200; i++)
        if (Hash[i] & 1)
        a[L++] = (char)i, Hash[i]--; 
    for (int i = 1; i <= 200; i++)
        if (Hash[i]) 
        while (Hash[i]--)
            a[R--] = (char)i; 
    
    L--;
    int ans, len; 
    for(ans = 1 ; ans <= n ; ans++) 
        if(n % ans) continue; 
        len = n / ans; 
        if((n - L) / 2 >= ans * (len / 2)) break; 
    
    printf("%d\n",ans);
    L = 1, R = n; 
    for(int i = 1 ; i <= ans; i++) 
        int ll = N + 10, rr = N + 10; 
        if(len & 1) cnt[rr++] = a[L++];
        for(int j = 1; j <= len/2; j++) 
            cnt[--ll] = a[R--]; 
            cnt[rr++] = a[R--]; 
        
        for(int j = ll; j < rr; j++)
            printf("%c",cnt[j]); 
        printf(" ");
    
//    system("pause");
    return 0; 

以上是关于CF883H的主要内容,如果未能解决你的问题,请参考以下文章

关于安排

CF 爆发者

[CF930E]/[CF944G]Coins Exhibition

CF怎么改名

dp专题

Codeforces | CF1028C Rectangles