【二分】十四届蓝桥杯python组例题

今天写写二分问题吧

1、二分查找数组元素

题目描述
给定一个数组,其采用如下代码定义:

int data[200];
for(i = 0 ; i < 200 ; i ++)data[i] = 4 * i + 6;

先给定某个数(在 data 数组中),请你求出它在数组中的位置。

输入描述
输入一个待查找的整数(该整数一定在数组data中)。

输出描述
输出该整数在数组中的指标。

n=eval(input())
print((n-6)//4)

这个很简单啦

2、扫地机器人

在这里插入图片描述

n,k=map(int,input().split())
a=[0]    #这里加个0是因为下面从1开始
for i in range(k):
  a.append(int(input()))
a.sort()  #从小到大排序

def check(d):  # 检查每一个清理距离是否能将走廊清理完成
  len=0   #覆盖长度,从最左端开始一直到最右端
  for i in range(1,k+1):
    if len+d>=a[i]:
      if len>a[i]:
        len=a[i]+d-1  #这里减1是因为自己本身也需要清理
      else:   #否则直接就是当前长度+d
        len+=d
    else:
      return False
  return len>=n
l,r=1,n   #最短是1,最长是n
while l<r:    #二分查找计算清扫范围
  mid=(l+r)//2
  if check(mid):
    r=mid
  else:
    l=mid+1
print((l-1)*2)

这道题我一开始想了很久,然后发现其实答案是所有清理机器人中最大清理距离的二倍,也就是说,我们将所有距离拿到检查函数中去试,通过二分找到正好全部清理的最小步长 *2
检查函数:从第一个位置,通过二分法一个位置一个位置输入,如果加上mid后包含这个点,就判断这个点是在mid的左边还是右边,通过循环,如果每个点清理距离都能覆盖就True,否则就False.
可能解释的不太清晰,欢迎留言讨论

3、调石头

在这里插入图片描述

L,N,M=map(int,input().split())
stone=[]
for i in range(N):
  stone.append(int(input()))

def check(d):
  num=0
  pos=0
  for i in range(0,N):
    if (stone[i]-pos<d):
      num+=1
    else:
      pos=stone[i]
  if num<=M: return True
  else: return False

l,r=1,L
while(l<r):
  mid=l+(r-l)//2
  if check(mid):
    l=mid+1
  else:
    r=mid-1

if check(l):
  print(l)
else:
  print(l-1)

因为都是二分问题,代码比较相似,通过上面一题,现在我明白二分是啥意思了
首先读题,让我们移走石头,找到移走之后 石头之间的最短跳跃距离的最大值,就是让选手跳远一点,但是别批了跨(bushi),逐个间距输入,保证可移动石头的数量不超过规定,比如把最大值输入,所有石头都能动,最小值又没有石头能动,所以通过二分查找位置。

4、一元三次方程求解

在这里插入图片描述

扫描二维码关注公众号,回复: 14919027 查看本文章
a,b,c,d=map(float,input().split())
def y(x):
  return a*x*x*x+b*x*x+c*x+d

for i in range(-100,100):
  left=i
  right=i+1
  y1=y(left)
  y2=y(right)
  if y1==0:
    print("{:.2f}".format(left),end=" ")
  if y1*y2<0:
    while right-left>=0.001:
      mid =(left+right)/2
      if y(mid)*y(right)<=0:
        left=mid
      else:
        right=mid
    print("{:.2f}".format(left),end=" ")

通过前面三题的学习,这道相信你已经得心应手了,就是一个高中的函数证明题,要记住输入是浮点小数,精确到后两位

5、123

在这里插入图片描述

n=int(2e6+1)
def getp(x):return x*(x+1)//2
def gets(x):return x*(x+1)*(x+2)//6
def search(x):
    l,r=1,n-1
    while l<r:
        mid=(l+r)>>1
        if getp(mid)>=x:r=mid
        else:l=mid+1
    return l,x-getp(l-1)
def solve(l,r):
    pl,nl=search(l)#第pl组的第nl个数
    pr,nr=search(r)
    return gets(pr-1)-gets(pl-1)-getp(nl-1)+getp(nr)
T=int(input())
for _ in range(T):
    l,r=map(int,input().split())
    print(solve(l,r))

先找位置,在带入函数返回对应位置的值
gets-getp=对应位置的值

相信聪明的你应该看出规律了
二分的例题大同小异,主要是找准方法和位置,巧用关系和基础数学知识,二分的例题就介绍到这里了,我们下次再见

猜你喜欢

转载自blog.csdn.net/weixin_53415043/article/details/128891964