import java.io.*;
import java.util.Arrays;
/**
* 最佳植树位置
* 小明在直线的公路上种树,现在给定可以种树的坑位的数量和位置,以及需要种多少棵树苗
* 问树苗之间的最小间距是多少时,可以保证种的最均匀(两棵树苗之间的最小间距最大)
* 输入描述:第一行一个整数:坑位的数量
* 第二行以空格分隔的数组:坑位的位置
* 第三行一个整数:需要种植树苗的数量
* 输出描述:树苗之间的最小间距
*/
public class BestTreePlantingLocation {
private static String line;
/**
* 坑位数
*/
private static int length;
/**
* 一共要种几棵数
*/
private static int totalTree;
private static String[] strArr;
/**
* 坑位数组
*/
private static int[] spots;
/*
7
13 11 8 7 6 3 1
3
------------------------
6
*/
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
line = in.readLine();
length = Integer.parseInt(line);
line = in.readLine();
strArr = line.split(" ");
//坑位正序排序
spots = Arrays.stream(strArr).mapToInt(Integer::parseInt).sorted().toArray();
line = in.readLine();
totalTree = Integer.parseInt(line);
out.println(bestTreePlantingLocation());
out.flush();
in.close();
out.close();
}
/**
* 二分法计算最佳植树位置
*/
private static int bestTreePlantingLocation(){
int low = 0;
//最大间距为坑位排序后最后一个位置与第一个位置的差
int high = spots[length - 1] - spots[0];
int result = -1;
//二分循环
while (low <= high) {
int mid = low + (high - low) / 2;
//在mid间距能种下要求棵数的前提下,求最远间距
if (isValidGap(mid)) {
result = mid;
low = mid + 1;
} else {
high = mid - 1;
}
}
return result;
}
/**
* 在给定间距下,是否能种下所有树
* @param gap 树间距
* @return 按当前间距种下的树是否大于等于树总数
*/
private static boolean isValidGap(int gap) {
//已种棵树
int count = 1;
//上一棵的坑位
int lastSpot = spots[0];
//从1号坑位开始遍历
for (int i = 1; i < length; i++) {
//当前位置与上一棵树的间距大于等于指定值
if (spots[i] - lastSpot >= gap) {
//则种下新树
count++;
//上一棵的坑位更新为当前位置
lastSpot = spots[i];
}
}
//种的棵树是否超过或刚好等于总棵数
return count >= totalTree;
}
}
【二分法】最佳植树位置
文章介绍了如何使用Java编程语言,通过二分查找算法解决公路植树问题,找到在给定坑位和树苗数量下,保证树苗均匀分布所需的最小间距。
摘要由CSDN通过智能技术生成