解题思路:

先理解题目,会给出隔间的编号和有几头牛,将牛尽可能分远的住进隔间,使任意两头牛之间的最小距离尽可能的大,问这个最小距离最大是多大

以给出的数据为例:

5 3
1 2 8 4 9

这五个隔间可以任意选三个住牛,可以是1 2 4,1 2 8 但是这样有的牛就会挨的太近了,还有更远的分法:1 4 9

所以答案输出牛之间的最小距离(4-1)=3

我们先将房间号进行排序,然后得出可能的最大距离为(max-min+1)/牛的数量

从最大的距离到1开始遍历,查看每头牛都在这个距离下是不是能全住进房间,能就输出这个距离,结束遍历,不能就继续遍历


这样做最坏的情况下的时间复杂度是n^2,数据规模是1,000,000,000,可能会时间超限

所以这里在查找距离的时候使用二分查找,时间复杂度是nlogn,

当然,在对房间号进行排序的时候也不能使用简单的冒泡排序等,那样时间复杂度也会变成n^2

这是使用c语言自带的排序,它在头文件stdlib.h里,是使用快速排序进行实现的,时间复杂度是nlogn


参考代码:

#include <stdio.h>
#include <stdlib.h>
  
int gg(const void *x,const void *y){
    return *(int *)x-*(int *)y;//从小到大排序
}
  
int n,m,p[100001]={0};//全局变量不用传递,m是牛的数量
  
int check(int z){
    int i;
    int count=1;//第一个牛舍放牛
    int k=p[0]+z;
    for(i=1;i<n;i++){
        if(p[i]>=k){//后面的牛舍要满足大于等于k才能放牛
            count++;
            k=p[i]+z;
        }
    }
    if(count>=m){//可以放的位置超过牛的数量
        return 1;
    }else{
        return 0;
    }
}
  
int main ()
{
    int i;
    int x=0,y=0,z=0;
    scanf("%d %d",&n,&m);
    for(i=0;i<n;i++){
        scanf("%d",&p[i]);
    }
    qsort(p,n,sizeof(p[0]),gg);//排序
      
    x=1;
    y=(p[n-1]-p[0]+1)/m;
    z=(x+y)/2;
    while(x<=z){//二分查找
        if(check(z)==0){//如果返回值是0说明z的值较大,要向小的一方查找
            y=z-1;
        }else{
            x=z+1;
        }
        z=(x+y)/2;
    }
    printf("%d",z);
      
    return 0;
}


点赞(0)
 

0.0分

5 人评分

C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:

一点编程也不会写的:零基础C语言学练课程

解决困扰你多年的C语言疑难杂症特性的C语言进阶课程

从零到写出一个爬虫的Python编程课程

只会语法写不出代码?手把手带你写100个编程真题的编程百练课程

信息学奥赛或C++选手的 必学C++课程

蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程

手把手讲解近五年真题的蓝桥杯辅导课程

评论列表 共有 4 条评论

Carmen 1年前 回复TA
很棒啊,原来是酱紫二分捏
指针原来是套娃的 1年前 回复TA
@WTcrazy 46行需要根据check函数的结果进行调整,放在上面没有check的结果
WTcrazy 1年前 回复TA
请问46行代码为啥放40行下面会只能过70样例
JIeJaitt 2年前 回复TA
原来这个网站还有人用