Palindromes Coloring(1400)Codeforces Round #764 (Div. 3)

D. Palindromes Coloring
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
You have a string 𝑠 consisting of lowercase Latin alphabet letters.

You can color some letters in colors from 1 to 𝑘. It is not necessary to paint all the letters. But for each color, there must be a letter painted in that color.

Then you can swap any two symbols painted in the same color as many times as you want.

After that, 𝑘 strings will be created, 𝑖-th of them will contain all the characters colored in the color 𝑖, written in the order of their sequence in the string 𝑠.

Your task is to color the characters of the string so that all the resulting 𝑘 strings are palindromes, and the length of the shortest of these 𝑘 strings is as large as possible.

Read the note for the first test case of the example if you need a clarification.

Recall that a string is a palindrome if it reads the same way both from left to right and from right to left. For example, the strings abacaba, cccc, z and dxd are palindromes, but the strings abab and aaabaa — are not.

Input
The first line of input data contains a single integer 𝑡 (1≤𝑡≤104) — the number of input data sets in the test.

The descriptions of the input data sets follow.

The first line of the description of each input data set contains two integers 𝑛 and 𝑘 (1≤𝑘≤𝑛≤2⋅105) — the length of the string and the number of colors in which its letters can be painted. The second line of the description of each input data set contains a string 𝑠 of length 𝑛 consisting of lowercase letters of the Latin alphabet.

It is guaranteed that the sum of n over all test cases does not exceed 2⋅105.

Output
For each set of input data, output a single integer — the maximum length of the shortest palindrome string that can be obtained.

Example
inputCopy
10
8 2
bxyaxzay
6 3
aaaaaa
6 1
abcdef
6 6
abcdef
3 2
dxd
11 2
abcabcabcac
6 6
sipkic
7 2
eatoohd
3 1
llw
6 2
bfvfbv
outputCopy
3
2
1
1
1
5
1
1
3
3
Note
In the first test case, 𝑠=“bxyaxzay”, 𝑘=2. We use indices in the string from 1 to 8. The following coloring will work: 𝐛𝐱𝐲𝐚𝐱𝐳𝐚𝐲 (the letter z remained uncolored). After painting:
swap two red characters (with the indices 1 and 4), we get 𝐚𝐱𝐲𝐛𝐱𝐳𝐚𝐲;
swap two blue characters (with the indices 5 and 8), we get 𝐚𝐱𝐲𝐛𝐲𝐳𝐚𝐱.
Now, for each of the two colors we write out the corresponding characters from left to right, we get two strings 𝐚𝐛𝐚 and 𝐱𝐲𝐲𝐱. Both of them are palindromes, the length of the shortest is 3. It can be shown that the greatest length of the shortest palindrome cannot be achieved.

In the second set of input data, the following coloring is suitable: [1,1,2,2,3,3]. There is no need to swap characters. Both received strings are equal to aa, they are palindromes and their length is 2.
In the third set of input data, you can color any character and take it into a string.
In the fourth set of input data, you can color the 𝑖th character in the color 𝑖.
In the fifth set of input data can be colored in each of the colors of one character.
In the sixth set of input data, the following coloring is suitable: [1,1,1,1,1,2,2,2,2,2,0]. Rearrange the characters so as to get the palindromes abcba and acbca.

题意 :

  • 给一字符串,问是否能将这字符串分成m个非连续子序列,这m个子序列的并集不需要是这个字符串,满足在任意交换若干次顺序后,这m个子序列都是回文串,要求这m个子序列中最短的长度最大,求这个最大长度

思路 :

  • 因为要使最短的长度最大,因此要使这m个中的每一个尽可能长度趋向相等
  • 发现,任意数量的偶数对都可以构成回文串,且最多可以加上一个单独的构成回文串
  • 因此,统计偶数对和被剩下的字符的个数,如果偶数对数量不足m个,说明偶数对无法均分,那么答案为1;如果大于等于m个,先均分偶数对给m个子序列,偶数对中剩余的部分用作单独的字符,如果单独的字符大于等于m个,也就是能让m个子序列中每一个都得到一个单独的字符,那么答案再加一,如果不能,就不加
  • 反思,多组数据,初始化
#include <iostream>
#include <cstring>
#define endl '\n'
using namespace std;

const int N = 30;

int num[N];

void solve()
{
    int n, m;
    string s;
    cin >> n >> m >> s;
    
    memset(num, 0, sizeof num);
    
    for (auto ch : s) num[ch - 'a'] ++ ;
    
    int pair = 0, single = 0;
    for (int i = 0; i < 26; i ++ )
    {
        pair += num[i] / 2, single += num[i] % 2;
    }
    
    int ans;
    if (pair < m) ans = 1;
    else
    {
        ans = pair / m * 2;
        int remain = pair % m * 2;
        single += remain;
        ans += min(single / m, 1);
    }
    
    cout << ans << endl;
}

int main()
{
    ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    
    int _; cin >> _;
    while (_ -- )
        solve();
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值