首先题目如下:
一开始看到题目我是没有任何思路的,于是根据各大网站上各位大佬的解题思路(小弟膜拜)以及我自己的理解,便成功的解决了这道题目。同时发布博客也是为了加深自己的理解。
题目要求我们找到水流布满整个管道的最早时间,据此我们可以推断出对于任意的时间
大于
,此时都能检测到水流,小于此值便检测不到,这是不是很像寻找一个临界值呢?而二分查找能够在
的时间内完成这个要求。对于每一个时间点我们检测一下当前是否能够布满整个管道区间。于是乎,两个算法便能够很好的解决这样一个问题了:二分查找+区间合并判断
1.二分查找算法设计
n, length = map(int,input().split())
ls = []
for i in range(n):
gd, sk = map(int,input().split())
ls.append((gd,sk))
#一定要理解这里的left和right,均表示时间
left, right = 1, 10**10 #右端点范围的设置一定要大
while left < right: #二分查找满足要求的时间
mid = (left + right)//2
if check(mid,ls,length): #区间合并判断函数,后面会详细设计
right = mid
else:
left = mid+1
print(left)
2.区间合并判断函数
def check(Ti,ls,length):
qj = []
for (x,y) in ls:
if Ti>=y:
qj.append((x-(Ti-y),x+(Ti-y))
if len(qj) == 0:
return False
qj.sort()
if qj[0][0] > 1:
return False
r = qj[0][1]
for i in range(1,len(qj)):
if qj[i][0] - r > 1:
#return False #此时区间并不能够连贯起来
break
else:
r = max(qj[i][1],r)
return r>=length
注意在设计check函数时,在判断两个相邻区间时,并不能直接return false。因为此时可能第一个区间无限大,可以直接包含整个管道。因此只能break,最后统一判断与管道长度的大小。