找规律的贪心模型
先看样例:
首先是对数据按照字典序进行了排序,然后划分成如下这样:
abcd就是当前情况下字典序最大的字符串最小的情况。
假如我划分为:
bacd大于a,但是也大于abcd,并不是最小的情况。
OK,理解了样例之后就来说说这道题的思想。
思想
首先划分为三种情况:
第一种
当 s[1]==s[n]时,也就是整个字符串都是一样的值,如下:
我们先试着划分一下,如下:
上面的情况x划分的段肯定是大于下面情况x划分的段的:
对于全相等的情况,我们可以发现个规律,就是把它们平均分成几份,如果有除不尽,就把多的那一份也加到x段上,这样x就是符合最大情况中最小的情况。
第二种情况
当s[1]==s[x]时,如下:
此时这种情况,s[x]和s[1]一样大,要想保证s[x]划分之后大于s[1],那么就要把s[x]后面的划给s[x],如下:
总结:如果s[1]==s[x],就把s[x]后面的划给s[x]
第三种情况
当s[1]!=s[x]时,如下:
这种情况下s[x]的字典序已经比s[1]大了,那么我们就要考虑最小的情况了,我们把s[x]后面的东西全部给s[1],s[1]也不会比s[x]大,并且s[x]就变为最小情况了,一举两得。
划分如下:
小结:s[1]!=s[x]时,把s[x]后面的一坨划给s[1],s[x]单独划分
code
#include <iostream>
#include<algorithm>
using namespace std;
const int N=1e6+10;
char s[N];
int main()
{
int n=0,x=0;cin>>n>>x;
cin >> s+1;
sort(s+1,s+1+n);
if(s[1]==s[n]) //相等情况
{
for(int i=1;i<=n/x+(n%x?1:0);i++) //平分为x段。可能会有多的,如果有多的那就是多1,如果没多的就是0
{
cout<<s[i];
}
}
else if(s[1]==s[x])
{
for(int i=x;i<=n;i++)cout<<s[i]; //从x开始到结尾
}
else
{
cout<<s[x]; //只输出s[x],s[x]后面全部给s[1]
}
return 0;
}