CF-Round #638-div2-C题

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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

娃娃酱斯密酱

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值