二分-Aggressive cows
描述:农夫 John 建造了一座很长的畜栏,它包括N (2 <= N <= 100,000)个隔间,
这些小隔间依次编号为x1,...,xN (0 <= xi <= 1,000,000,000).但是,John的
C (2 <= C <= N)头牛们并不喜欢这种布局,而且几头牛放在一个隔间里,他们就要
发生争斗。为了不让牛互相伤害。John决定自己给牛分配隔间,使任意两头牛之间的
最小距离尽可能的大,那么,这个最大的最小距离是什么呢?
输入
第一行:空格分隔的两个整数N和C
第二行——第N+1行:分别指出了xi的位置
输出
每组测试数据输出一个整数,满足题意的最大的最小值,注意换行。
样例输入
5 3
1
2
8
4
9
样例输出
3
思路:我理解N值是告诉有几个x的值,x值可以理解为一个栅栏柱,使任意2头牛之间间隔
距离尽可能的大,求这个最大值。
第1种方法可以穷举遍历:Xn/C,x坐标的最大值除以C,得到距离D的最大值,也就是所有
的值不会超过这个值,所以可以从Xn/C开始遍历依次尝试这个距离,不符合就减1,如果符合
条件,则该值既是所求的最大值。考虑到Xn的最大值有1000000000,这样遍历会运算特别慢,
因此第二种方法,就是利用二分的思路来解决该问题。
第2种方法就是在取距离D的时候,利用了二分思想。
其实就是先假设一个距离D,然后从第一个坐标点开始,加上这个距离D,如果第2个坐标
点小于该值,则遍历第3个坐标点,如果第3个坐标点与第1个坐标点的距离大于D,那么说明可以
放下1头牛,则从第3个坐标点再加上距离D,类似第1点一样,判断与第4个点的距离是否大于
距离D,如果点之间的距离符合D的,则sum加1,遍历结束后,如果sum大于C,那么说明该距离D
可以放下C头牛,否则不能放入C头牛。
Python算法实现:
1 N,C = 0,0 2 3 def Ok(d,listSorted): 4 sum,firstValue = 1 ,listSorted[0] 5 for i in range(1,len(listSorted)): 6 #当前i位置的值与前面点的值距离大于等于v,说明这个距离可以放下一头牛 7 if listSorted[i] - firstValue >= d: 8 firstValue = listSorted[i] 9 sum+=1 10 #如果可以放下的数量大于等于牛的数量,说明这个距离能满足要求放完牛 11 if sum >= C : 12 return True 13 else: 14 return False 15 16 def main(): 17 list1 = list(map(int,input().split(" "))) 18 list2 = [] 19 global N,C 20 N = list1[0] 21 C = list1[1] 22 for i in range(N): 23 temp = int(input()) 24 list2.append(temp) 25 list2.sort() 26 low, high, mid = list2[0], list2[N-1], 0 27 #当相减的距离是1的时候,则遍历结束 28 while(high - low > 1): 29 d = int((low+high)/2) 30 #true,说明这个距离d符合要求,可以再尝试把d的距离变大,看是否符合放下C头牛 31 if Ok(d,list2): 32 #当最后这个low的赋值,既是所求的值 33 low = d 34 #false,说明该距离太大,所以把mid赋值给high,让距离D的区间缩小 35 else: 36 high = d 37 print("%d"%low) 38 if __name__ == "__main__": 39 main()