第十四届蓝桥杯省赛Python大学B组试题D:管道

首先题目如下:

一开始看到题目我是没有任何思路的,于是根据各大网站上各位大佬的解题思路(小弟膜拜)以及我自己的理解,便成功的解决了这道题目。同时发布博客也是为了加深自己的理解。

题目要求我们找到水流布满整个管道的最早时间Ti,据此我们可以推断出对于任意的时间t大于Ti,此时都能检测到水流,小于此值便检测不到,这是不是很像寻找一个临界值呢?而二分查找能够在nlogn的时间内完成这个要求。对于每一个时间点我们检测一下当前是否能够布满整个管道区间。于是乎,两个算法便能够很好的解决这样一个问题了:二分查找+区间合并判断

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,最后统一判断与管道长度的大小。

  • 8
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值