需要强调的是,我这个代码并不是刷题的标准答案(比如输入和输出的地方),只是提供思路,目前不是很想正儿八经去刷题。
python代码及其注释如下:
'''
Uoj148 【NOIP2015】跳石头
跳石头比赛,河道两岸放置代表起点与终点的巨大岩石,此外在河道中央散布N块巨大岩石
要求选手从起点经过每一块岩石之后跳向终点
目标:组委会计划移走一些岩石,使得选手们的最短跳跃距离最长,至多移走M块岩石
输入要求:三个整数:起点到终点的距离L,起点和终点之间的岩石数N,移走的岩石数M,L>=1, N>=M>=0
输入N个整数,每个整数Di表示第i块岩石到起点的距离,D是单调递增序列,没有重复
输出:最长的最短跳跃距离
'''
import math
# 输入
L = 25
N = 5
M = 2
D = [2,11,14,17,21]
# 相邻石头间隔:2,9,3,3,4,4
# 预期输出: 4
# 最短跳跃距离的范围: [所有岩石之间的最短距离,起终点之间的距离],采用二分法
high = L
low = D[0]
# 除了起点之外,每个点到前一个点的距离
DL = []
DL.append(0)
DL.append(D[0])
for i in range(1, N):
DL.append(D[i])
d = D[i] - D[i-1]
if d < low:
low = d
DL.append(L)
# DL = [0,2,11,14,17,21,25]
while low < high:
# 暂定的 min(distance)
mid = math.floor((high + low) / 2)
pre_stone = 0
# 实际移走的石头数量
temp_m = 0
distance = []
for j in range(1, len(DL)):
if j == (len(DL) - 1):
distance.append(DL[j] - pre_stone)
break
if (DL[j] - pre_stone) < mid:
temp_m = temp_m + 1
# DL = [0,2,11,14,17,21,25]
else:
distance.append(DL[j] - pre_stone)
pre_stone = DL[j]
if temp_m > M:
high = mid - 1
break
# DL = [0,2,11,14,17,21,25]
if temp_m == M:
break
elif temp_m < M:
low = mid + 1
print("跳石头最小距离的最大值 ", min(distance))
print(distance)
运行结果: