蓝桥杯 1.分糖果 找规律贪心模型

207 阅读2分钟

1.分糖果 - 蓝桥云课 (lanqiao.cn)

找规律的贪心模型

先看样例:

image.png

首先是对数据按照字典序进行了排序,然后划分成如下这样:

image.png abcd就是当前情况下字典序最大的字符串最小的情况。

假如我划分为:

image.png

bacd大于a,但是也大于abcd,并不是最小的情况。

OK,理解了样例之后就来说说这道题的思想。

思想

首先划分为三种情况:

第一种

当 s[1]==s[n]时,也就是整个字符串都是一样的值,如下:

image.png 我们先试着划分一下,如下:

image.png 上面的情况x划分的段肯定是大于下面情况x划分的段的:

image.png

对于全相等的情况,我们可以发现个规律,就是把它们平均分成几份,如果有除不尽,就把多的那一份也加到x段上,这样x就是符合最大情况中最小的情况。

第二种情况

当s[1]==s[x]时,如下:

image.png 此时这种情况,s[x]和s[1]一样大,要想保证s[x]划分之后大于s[1],那么就要把s[x]后面的划给s[x],如下:

image.png

总结:如果s[1]==s[x],就把s[x]后面的划给s[x]

第三种情况

当s[1]!=s[x]时,如下:

image.png 这种情况下s[x]的字典序已经比s[1]大了,那么我们就要考虑最小的情况了,我们把s[x]后面的东西全部给s[1],s[1]也不会比s[x]大,并且s[x]就变为最小情况了,一举两得。 划分如下:

image.png

小结: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;
}