Codeforces Round #638 (Div. 2) ABC

A - Phoenix and Balance

题意:

思路:

代码:

 

B - Phoenix and Beauty

题意:给定长为n的序列a,1<=a[i]<=n,你可以在任意位置插入范围[1,n]的数字,让所有长为k的子段和一致。问是否可以做到,如果可以,输出最终序列。

思路:

代码:

 

C - Phoenix and Distribution

题意:给定一个长为n的字符串,把它的每个字母分到k个小字符串中,问这k个小字符串中字典序最大的字符串 最小是什么样。

贪心策略:

1. 将原字符串按字典序从小到大排序

2. 从前往后k个字母均摊到k个空串中(现在k个字符串每个都包含1个字母)

3. 如果原串只剩一种字母,在 以最小字母开头的字符串中 均摊

4. 否则剩下全部字母加到 最小字母的后面

5. 答案就是第一个字符串和第k个字符串中的较大者

因为要让最大的字符串最小,

如果只剩1种字符,e.g. k=3, ab, ab, b | abb, a, b,要把剩下的一种字符'b'均摊,因为abb大于ab,还要均摊到最小字母的字符串后,因为如果没有这样,会使答案变大

如果剩下不止一种字符,要把剩下的所有字符全加到最小字母后e.g. k=2, abz, ab | abbz, a,因为剩下的最大的那个字符‘z’,要让它在字符串中的位置尽可能靠后,才能使答案最小

//好吧 希望我的逻辑更流畅些。。

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        int n,k;
        scanf("%d%d",&n,&k);
        string str;
        cin>>str;
        sort(str.begin(),str.end());

        //以最小字母开头的字符串有cnt个
        auto pos=upper_bound(str.begin(),str.end(),str[0]);
        int cnt;
        if(pos==str.end()) cnt=k;
        else cnt=pos-str.begin();

        string s1,s2;
        s1+=str[0],s2+=str[k-1];//备选答案
        
        if(str[k]!=str[n-1]) { //剩下的字符不止1种
            s1+=str.substr(k);
        }else{ //只剩一种字符
            s1.insert(s1.end(),(n-k+cnt-1)/cnt,str[k]);
            //均摊到每个 最小字母开头字符串 的剩下的这一种字符 有 (n-k+cnt-1)/cnt 个//(n-k)/cnt 有余数则+1
        }
        cout<<max(s1,s2)<<endl;
    }
    return 0;
}

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值