zoukankan      html  css  js  c++  java
  • Codeforces 883H

    题目链接:http://codeforces.com/problemset/problem/883/H

    Time limit: 3000 ms

    Memory limit: 262144 kB

    Kolya has a string s of length n consisting of lowercase and uppercase Latin letters and digits.

    He wants to rearrange the symbols in s and cut it into the minimum number of parts so that each part is a palindrome and all parts have the same lengths. A palindrome is a string which reads the same backward as forward, such as madam or racecar.

    Your task is to help Kolya and determine the minimum number of palindromes of equal lengths to cut s into, if it is allowed to rearrange letters in s before cuttings.

    Input

    The first line contains an integer n (1 ≤ n ≤ 4·105) — the length of string s.

    The second line contains a string s of length n consisting of lowercase and uppercase Latin letters and digits.

    Output

    Print to the first line an integer k — minimum number of palindromes into which you can cut a given string.

    Print to the second line k strings — the palindromes themselves. Separate them by a space. You are allowed to print palindromes in arbitrary order. All of them should have the same length.

    Example

    Input
    6
    aabaac
    Output
    2
    aba aca
    Input
    8
    0rTrT022
    Output
    1
    02TrrT20
    Input
    2
    aA
    Output
    2
    a A

    题意:

    给出一个长度为n的字符串,可以任意的重新排列,求最小能将该字符串切割成等长的多少份,使得每一份均为回文串。

    题解:

    (引用来自http://blog.csdn.net/mMingfunnyTree/article/details/78306596的思路。)

    不难想到,记录下每个字符出现的次数,要么是出现奇数次,要么是出现偶数次,记为cnt[i]。

    假设长度为n的字符串,切割成m份,每份长为len(即 m * len = n),那么显然,len要么是奇数,要么是偶数;

    若len为偶数,根据回文串的性质,就会推出 所有字符出现的次数都为偶数;

    换句话说,一旦cnt[ '0'~'9' & 'a'~'z' & 'A'~'Z' ]中任意一个cnt[i]为奇数,len就必须为奇数;

    那么我们先把情况分成两种:

      所有cnt[i]均为偶数,这时len可以为偶数,而要m最小,显然此时m可以为1,len==n;

      把字符串调整为回文串输出即可。

      存在一些cnt[i]为奇数,这时len必须为奇数,根据奇数长度的回文串的性质可知:

      每个回文串,中间位置单独一个字符;剩余均为成对出现的字符;

      例如"aabbbaa":单独一个字符'b';成对出现字符'a','a','b';

      这样我们就不难想到一种思路:

        遍历 '0'~'9' & 'a'~'z' & 'A'~'Z',根据cnt[i]的奇偶性,分成两组:odd和even;

        odd集合中每个元素代表一个成单的字符;even集合中每个元素代表一对成双的字符;

        这样一来,目标情况是:

        odd集合的size正好为m,这样odd内的每个元素正好作为一个回文小串的中间位,

        而even集合中的元素应当正好可以平均分配到m个回文小串中( 即满足m | even.size()  <=>  odd.size() | even.size() );

        那如果even.size()不能平均分成m份怎么办?

        此时,显然只能把even中的一个元素,即一对字符,拆开来,当做两个成单字符;即even.size() -= 1 , m += 2;

        反复如此,直到even中的元素可以平均分配成m份为止(even.size()==0时必然可以平均分配,此时m = odd.size() = n );

    AC代码:

    #include<bits/stdc++.h>
    #define MAX 400005
    using namespace std;
    int n;
    char str[MAX];
    int cnt[130]={0};
    vector<char> odd,even;
    int main()
    {
        scanf("%d",&n);
        scanf("%s",&str);
        for(int i=0;i<n;i++) cnt[str[i]]++;
        for(int i='0';i<='z';i++)
        {
            if(cnt[i]<=0) continue;
            if(cnt[i]%2)
            {
                odd.push_back((char)i);
                cnt[i]--;
            }
            while(cnt[i])
            {
                even.push_back(i);
                cnt[i]-=2;
            }
        }
    
        char ans[MAX];
        if(odd.empty())
        {
            printf("1
    ");
            for(int i=0;i<n/2;i++) ans[i]=ans[n-1-i]=even[i];
            ans[n]='';
            printf("%s
    ",ans);
            return 0;
        }
    
        while(even.size() % odd.size())
        {
            odd.push_back(even.back());
            odd.push_back(even.back());
            even.pop_back();
        }
    
        printf("%d
    ",odd.size());
        int len=n/odd.size();
        while(!odd.empty())
        {
            ans[len/2]=odd.back();
            odd.pop_back();
            for(int j=0;j<len/2;j++)
            {
                ans[j]=ans[len-1-j]=even.back();
                even.pop_back();
            }
            ans[len]='';
            printf("%s ",ans);
        }
    }
  • 相关阅读:
    github上fork的项目,如何同步原作者更新的内容?
    设计模式-简单工厂模式详解
    设计模式-建造者模式详解
    设计模式-原型模式详解
    设计模式-单例模式详解
    SqlServer断开所有连接
    Winform重写键盘按键事件
    从拖拉控件编程到面向设计编程(一)
    Springboot vue 前后分离 跨域 Activiti6 工作流 集成代码生成器 shiro权限
    java 微信自定义菜单 java微信接口开发 公众平台 SSM redis shiro 多数据源
  • 原文地址:https://www.cnblogs.com/dilthey/p/7717534.html
Copyright © 2011-2022 走看看