洛谷P4447 [AHOI2018初中组] 分组 (ac代码+注释)

题目

题解

思路

这道题我是用贪心加二分查找做的,写的像答辩,随便看看了,我们要让人数最少的组人数最大值,

所以我们每次加入组员的时候,把组员加入到人数最小的组,因为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);      
}

  • 10
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值