zoukankan      html  css  js  c++  java
  • CF883H

    CF883H

    题意:

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

    解法:

    大模拟一个。
    分别统计出现一次的字符和出现两次的字符,如果没有出现一次的字符,那么所有字符出现次数均为偶数,说明本身便可以排列成回文串。
    如果某个字符出现次数为偶次,可以拆分为多个 $ frac{cnt}{2} $ 个相同字符存入,如果出现次数为奇数次,则先存入单个统计并计数减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
    ",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; 
    }
    
  • 相关阅读:
    【STL】栈stack
    【简单思考】noip2010提高组 乌龟棋
    【水】noip2010提高组 机器翻译
    【dp概率与期望】pattern
    【快速幂+中等难度】Calculation 哈工大HITOJ2901
    hdu--4502--dp
    hdu--4432--好久没做题了.
    hdu--5019--开始参加bc了
    字符串排列后匹配
    输出n的全排列的字典序编号为k的全排列
  • 原文地址:https://www.cnblogs.com/Repulser/p/11396865.html
Copyright © 2011-2022 走看看