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

    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.

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

    题目大意:

    输入一个n,接下来输入一个长度为n的字符串,你需要对其进行重新排列,分成最少的回文串,并且每个串长都相等,输出分好的串的个数,然后输出分好的串,用空格分隔。

    解题思路:

    可以用向量存一下出现1次的字符和2次的字符,开两个vector,对于偶数出现的字符,直接存入vector,然后cnt -= 2,直到cnt == 0,对于vector中的元素,每一个都出现了两次,对于奇数次出现的,先存入出现一次的vector,然后按照两次的处理,先判断落单的字符是不是0个,如果是,则说明重排列形成1个回文串,正序逆序输出2次的vector的元素即可。如果不是,则判断偶次的 % 落单的字符个数等于0,如果不等于0则拿偶数次的去补,偶数次的-1,奇数次的+2(从偶数次那里过来),然后输出v.size()(落单的个数),表示回文串的个数,接下来每个回文的长度是n / v.size(),然后从偶数次的vector取len / 2,加上一个落单字符,再逆序取len / 2即可。这里有一个技巧,因为是vector,可以直接从后面取,取完直接pop_back()即可。

    Code:

    #pragma GCC optimize(2)
    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    #include <cmath>
    #include <vector>
    #include <map>
    #include <set>
    #include <cstring>
    using namespace std;
    const int N = 2e5 + 50;
    const int inf = 0x3f3f3f3f;
    map<char, int> mp;
    vector<char > v, v1;
    int main()
    {
    	int n;
    	string s;
    	cin >> n >> s;
    	for (int i = 0; i < n; i ++)//先统计每个字符出现的个数
    	    mp[s[i]]++;
    	for (char i = '0'; i <= 'z'; i ++)
    	{
    		if (!mp[i])  continue;
    		if (mp[i] & 1)//如果是奇数先取出1个作为落单的字符再按2次的进行操作
    		{
    			v.push_back(i);
    			mp[i]--;
    		}
    		while (mp[i])
    		{
    			v1.push_back(i);//每一个元素都出现过两次
    			mp[i] -= 2;
    		}
    	}
    	string ans = "";
    	if (v.empty())//表示没有落单的字符,直接输出1即可。
    	{
    		cout << 1 << endl;
    		for (int i = 0; i < n / 2; i ++)
    		  ans += v1[i];
    		cout << ans;
    		reverse(ans.begin(), ans.end());
    		cout << ans << endl;
    		return 0;
    	}
    	while (v1.size() % v.size())//如果不能整除则把2次出现的转移到落单的字符,比如落单的有3个,2次的有16个,则转移后是5个 15 个,符合条件
    	{
    		v.push_back(v1.back());
    		v.push_back(v1.back());
    		v1.pop_back();
    	}
    	cout << v.size() << endl;
    	int len = n / v.size();
    	while (v.size())
    	{
    		ans = "";
    		for (int i = 0; i < len / 2; i ++)//取len / 2
    		{
    			ans += v1.back();
    			v1.pop_back();
    		}
    		cout << ans;
    		cout << v.back();
    		v.pop_back();
    		reverse(ans.begin(), ans.end());//回文,进行逆序操作
    		cout << ans << " ";
    	}
    	cout << endl;
    	return 0;
    }
    
  • 相关阅读:
    pamamiko的学习笔记
    pamamiko的安装
    python基本语法1.1--十进制与十六进制数之间的相互转换
    mnist深入--用卷积神经网络改善mnist
    minst数据集怎么跑
    七大常见排序算法总结(Java语言)
    ubuntu 16.03 Anaconda Tensorflow(CPU)安装
    IntelliJ Idea 2017 免费激活方法
    Ubuntu下安装deb格式的软件
    win10下配置java环境
  • 原文地址:https://www.cnblogs.com/Hayasaka/p/14294170.html
Copyright © 2011-2022 走看看