题目
题解
思路
这道题我是用贪心加二分查找做的,写的像答辩,随便看看了,我们要让人数最少的组人数最大值,
所以我们每次加入组员的时候,把组员加入到人数最小的组,因为n最大1e5,如果直接遍历的话,时间复杂度为O(n),会爆掉,所以我们用更快的二分查找
同时我们发现如果是一个越新的小组,那么它的人数就会越少,又刚好符合我们的贪心策略,
所以说在我们查找的时候应该让它尽量靠右,也就是尽量增大,找到那个符合条件,且最新的那个小组来加入新组员
具体看下面代码(附带注释)
代码
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;
#define maxsize 100005
struct ac{
long long lastdata; //最新的那位组员的实力
int cnt; //该小组的组员数量计数器
};
struct ac a[maxsize];
int main(){
int n;
long long s[maxsize]={0};
int zong=1;//小组数量计数器
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%lld",&s[i]); //读入每个组员的实力
sort(s,s+n);//排序
a[0].lastdata=s[0]; //先开一个小组
a[0].cnt=1;
for(int i=1;i<n;i++){
int le=0,re=zong-1,mid; //二分查找
while(le<re){
mid=(le+re+1)/2; //+1是因为要让le越大越好
if(s[i]-1>=a[mid].lastdata) le=mid;
else re=mid-1;
}
if(s[i]-a[re].lastdata==1){ //如果有找到符合条件的小组的话
//就加入,然后结束这一轮循环
a[re].lastdata=s[i];
a[re].cnt++;
continue ;
}
//如果没有找到符合条件的小组,就会运行到这里,那么就开一个新的小组
a[zong].lastdata=s[i];
a[zong].cnt=1;
zong++;
}
int ma=a[0].cnt; //求最小值
for(int i=2;i<zong;i++)
ma=(ma>a[i].cnt)?a[i].cnt:ma;
printf("%d",ma);
}