CF-Round #638-div2-C题
C. Phoenix and Distribution
这道题贪心模拟题~
题目大意:给你一个字符串,让你把这个字符串分成k个字符串,其中顺序没有要求。问要使得分成的k个字符串中字典序最大的字符串尽可能地小,输出字典序最大地字符串。
本题思路:我们首先就是要把这个字符串排序啦~
我们的贪心思路就是尽可能的把最小的字母顺序的平均分配给这k个字符。
然后我们考虑分成地k个字符串地第一个字母。
如果原序列中最小的字符出现的次数小于k次,那么我们字典序最大的字符串就已经确定了,就是原序列中第k小的字符。直接输出即可。
比如字符串aaabbbb,当k = 4的时候,因为k = 4 > a出现的次数3.
所以字典序最大的字符串就是b,(i = 3时的b,是第4大的字符,下标从0开始)
如果原序列中最小的字符出现了k次以上
我们现在考虑这k个字符串的第一个字符肯定就是原序列的最小字符啦~
再考虑分配这k个字符串的第二个字符:
当我们分配完这k个字符串的第一个字符后剩下的字符串的字符不相等。
那我们的贪心策略就是把这些剩下的字符串全部加到一个字符串的后面,这样操作的当前字符串就是字典序最大的字符串,并且尽可能的最小化。
比如:aaaabbb,当k = 4时:
分配完第一个字符后:
第一个字符串:a
第二个字符串:a
第三个字符串:a
第四个字符串:a
剩下的字符串:abbb;
我们直接把abbb家到任意一个字符串后面即可。就是最小化最大的字典序的字符串了:aabbb(这里我们就不能平均分配了,平均分配我们不能得到最小序列的字符串)
当我们分配这k个字符串的第一个字符后剩下的字符串的字符都相等。
那我们的贪心策略就是把剩下的字符串平均分配给这k个字符串即可。
剩下的字符串数量若为x,那么操作剩下的字典序最大的字符串的分配个数就是:ceil(x / k);也可以写做:(x + k - 1) / k;
实时输出即可~
代码部分:
#include <bits/stdc++.h>
using namespace std;
int main()
{
int t;
cin >> t;
while (t--)
{
int n, k;
string s;
cin >> n >> k;
cin >> s;
sort(s.begin(), s.end());
if (s[0] != s[k - 1])//最小的k个字符不是完全相等。
{
cout << s[k - 1] << endl;
continue;
}
cout << s[0];
if (s[k] != s[n - 1])//剩下的字符不相等
{
for (int i = k; i < n; i++)
{
cout << s[i];
}
}
else//剩下的字符相等
{
int t = (n - k + k - 1) / k;//像上取整ceil
for (int i = 1; i <= t; i++)
{
cout << s[k];
}
}
cout << endl;
}
return 0;
}