蓝桥杯备战——基础算法(1)

  1.  二分查找算法介绍
  2. 二分算法实例
  3. 实例思路
  4. 代码

1、二分算法介绍

        1.1概念

        二分算法(Binary Search)是一种在排好序的数组中查找目标值的算法。它通过将目标值与数组中间元素进行比较,从而确定目标值可能存在的位置。如果目标值小于中间元素,就在数组的左半部分继续查找;如果目标值大于中间元素,就在数组的右半部分继续查找。通过每次将搜索范围缩小一半,最终可以快速找到目标值的位置或者确定其不存在。

        1.2时间复杂度       

        二分算法的时间复杂度为 O(log n),其中 n 为数组的长度。

        1.3二分算法的基本步骤

        1.确定搜索范围的起始点和终点。

        2.计算中间元素的索引,并取得该位置的元素值。

        3.将目标值与中间元素进行比较,以确定下一步搜索的方向。

        4.根据比较结果,缩小搜索范围并重复上述步骤,直至找到目标值或者确定其不存在。

2.二分算法实例——管道

        2.1问题描述

        有一根长度为 len 的横向的管道,该管道按照单位长度分为 len段,每一段的中央有一个可开关的阀门和一个检测水流的传感器。一开始管道是空的,位于 Li的阀门会在 Si 时刻打开,并不断让水流入管道。对于位于 Li的阀门,它流入的水在 Ti(Ti≥Si)时刻会使得从第 Li−(Ti−Si)段到第 Li+(Ti−Si)段的传感器检测到水流,求管道中每一段中间的传感器都检测到有水流的最早时间。

        2.2输入格式

        输入的第一行包含两个整数 n,len,用一个空格分隔,分别表示会打开的阀门数和管道长度。 接下来 n行每行包含两个整数 Li,Si,用一个空格分隔,表示位于第 Li段管道中央的阀门会在 Si时刻打开。

        2.3输出格式

        输出一行包含一个整数表示答案。

        2.4数据范围

        对于 30%30% 的评测用例,n≤200,Si,len≤3000;
        对于 70%70% 的评测用例,n≤5000,Si,len≤10^5
        对于所有评测用例,1≤n≤1051,1≤Si,len≤10^9,1≤Li≤len1,Li−1<Li。

        2.5输入样例

3 10
1 1
6 5
10 2

        2.6输出样例

5

      3.实例思路  

        根据题目可知,管道的最大长度len可以达到10^9,则可知最坏的情况为仅打开第一个阀门,打开的时间为10^9,则可得将在2*10^9-1的时候管道内充满水流。题目要求找到最短时间,则这个最短时间一定在0——2*10^9-1之间,取其中间数。采用二分查找的思想,当目的值小于这个中间数时,管道一定已经填满了,则在数组的左半部分查找;反之,管道一定未填满,则在数组的右半部分查找。重复以上步骤,直到找到最短时间位置。

        注意,打开的阀门不止一个,判断函数要遍历每一个打开阀门在取不同时间Ti(Ti≥Si)时,其到达的其它阀门。

        4.代码

def pan_duan(t1, l1, n2):
    num1 = [False] * l1
    for m in n2:
        if t1 >= m[1]:
            left = max(0, m[0] - (t1 - m[1]))
            right = min(l1 - 1, m[0] + (t1 - m[1]))
            for i in range(left, right + 1):
                num1[i] = True

    return all(num1)


def binary_search(len1, num2):
    start1 = 0
    end1 = pow(10, 9) * 2 - 1
    while start1 < end1:
        t = (end1 + start1) // 2
        if pan_duan(t, len1, num2):
            end1 = t
        else:
            start1 = t + 1

    return start1


# 输入处理
if __name__ == "__main__":
    num1, len1 = map(int, input().split())
    num2 = []
    for _ in range(num1):
        num2.append(list(map(int, input().split())))

    # 调用二分查找函数
    result = binary_search(len1, num2)
    print(result)

        第一次在发表文章,有任何不足之处,欢迎在评论区指出。

  • 10
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值