栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

二分查找学习笔记

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

二分查找学习笔记

最近在学习二分。

然后遇到一题:题目 - T^T online Judge

二分法

Problem Description

二分查找的基础

Input

多组测试数据

每组测试数据的第一行输入n,m表示数组的长度和询问的次数(1<=n,m<=105)

接下来一行是n个数字A0...An-1 满足 Ai<=Ai+1 (1<=Ai<=109)

然后输入m行,每行是一个数字Qi表示询问(1<=Qi<=109)

Output

对于每个询问,如果Qi在数组中出现过,输出两个数字分别第一次出现和最后一次出现的位置,如果Qi在数组中没有出现,则输出一个数字表示第一个大于Qi的数字的位置(如果没有任何数字大于Qi则输出n)

SampleInput

10 4 
3 3 3 5 5 5 6 7 7 7 
1 
5 
6 
10

SampleOutput

0 
3 
5 
6 
6 
10
#include

#define LL long long

LL half_search_end(LL *a, LL n, LL num)    // 取第一个比num大的位置
{
    LL start = -1;
    LL end = n;
    while (1)
    {
        LL mid = (start + end) / 2;
        if (mid == start || mid == end) return end;    // mid 最后一定会等于 start 或 end
        if (a[mid] > num) end = mid;
        else start = mid;
    }
}

LL half_search_start(LL *a, LL n, LL num)    // 取最后一个比 num 小的位置
{
    LL start = -1;
    LL end = n;
    while (1)
    {
        LL mid = (start + end) / 2;
        if (mid == start || mid == end) return start;
        if (a[mid] < num) start = mid;
        else end = mid;
    }
}

int main()
{
    LL n, m;
    while (scanf("%lld %lld", &n, &m) != EOF)
    {
        LL a[100005];
        for (LL i = 0; i < n; i++)
        {
            scanf("%lld", &a[i]);
        }
        for (LL i = 0; i < m; i++)
        {
            LL num;
            scanf("%lld", &num);
            LL res = half_search_end(a, n, num);
            if (a[res - 1] == num)    // 若出现 num,则 res-1 为最后一个 num 的位置
            {
                printf("%lld %lldn", half_search_start(a, n, num) + 1, res - 1);
            }
            else
            {
                printf("%lldn", res);
            }
        }
    }
    return 0;
}

其中的两个函数可以当模板使用。

对这两个函数的结果进行处理可以应用在更多的地方。

 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/702498.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号