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;
    }
    
  • 相关阅读:
    Shell与if相关参数
    Linux盘符漂移问题
    shell脚本,每5个字符之间插入"|",行末不插入“|”
    paste:linux合并两个文件中的列(左右合并)
    关于bc 的scale .
    RxJS与观察者模式
    什么是虚拟DOM
    JS设计模式
    JS自定义事件
    原生js实现拖拽功能
  • 原文地址:https://www.cnblogs.com/Hayasaka/p/14294170.html
Copyright © 2011-2022 走看看