zoukankan      html  css  js  c++  java
  • 【思维】C. Phoenix and Distribution

    C. Phoenix and Distribution

    题意:给定长度为n的字符串s,将s任意拆分成k个部分,求k个部分中字典序最大的最小字典序

    思路:

    因为是任意拆分,所以将s中的字母从小到大排序,那么字典序最小的字母为s[1],记它的个数为p

    实际上要求的还是最小字典序,那么在构造这k个部分的过程中,应始终选用可选的最小字母

    有三种情况:

    1.(p<k),则(k)个部分中必有(p)个以s[1]开头,而第(p+1)个则以更大的字母开头,故第(k)个部分应以s[k]这个字母为开头,那么它一定是字典序最大的那个。由于要求最小字典序,则不应在其后继续接字母,剩余字母都将安排到(p)个部分中。所以答案应该为s[k]

    2.(k≤p<n),则(k)个部分都以s[1]为开头,答案应在后直接接剩下所有的串,就直接能保证满足题意

    3.(p=n),则k个部分平均分配所有字母才能保证答案是最小的字典序,答案应该是(n/k)个s[1]

    #include<iostream>
    #include<algorithm>
    using namespace std;
    const int maxn = 3e5 + 10;
    typedef long long LL;
    LL gcd(LL a, LL b) {return b ? gcd(b, a % b) : a;}
    LL lcm(LL a, LL b) {return a * b / gcd(a, b);}
    char s1[100000 + 10];
    int main()
    {
    	int t; cin >> t; while (t--){
    		int n, k;
    		cin >> n >> k;
    		cin >> s1+1;
    		sort(s1+1, s1 + n+1);//找出字典序前k小的字母
    		if (s1[1] != s1[k]) cout << s1[k] << endl;
    		//如果与s1[1]相同的字母小于k个,那么符合要求的答案必为s1[k]这个字母
    		else if (s1[n] != s1[k + 1]) cout << s1[1] << s1 + k + 1 << endl;
    		//如果与s1[1]相同的字母大于等于k个,但不是全部都相同
    		//那么答案以s1[1]开头,后面接从k+1个字母开始的串
    		else {
    			//全部相同,平均分配
    			cout << s1[1];
    			for (int i = 1; i <= (n - 1)/ k; i++) cout << s1[k + 1];
    			cout << endl;
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    UE 实现英雄联盟手游 备注名文本超框自动截断
    Qt使用msvc编译MySQL驱动
    Qt5打包发布的大小也太坑爹了
    查看迅雷等资源共享工具正在上传的文件
    bugfree安装过程和配置
    文件上传后台和前台代码(文件下载也是)
    SqlHelper.cs的介绍
    站点添加联系QQ留言(阿里巴巴应该也类似)
    http://blog.csdn.net/songlipeng2003/article/details/1513456
    转(学习中)
  • 原文地址:https://www.cnblogs.com/streamazure/p/12891148.html
Copyright © 2011-2022 走看看