二分查找

二分查找是一种在有序数组中查找特定元素的算法。它的基本思想是将数组分成两部分,判断目标元素在哪一部分中,然后继续在该部分中进行查找,直到找到目标元素或者确定目标元素不存在为止。这种算法的时间复杂度为O(log n),比线性查找的时间复杂度O(n)更快。

例如,寻找n个从小到大顺序的中指定的数字位置,可以:

复制代码
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n,a[1000010],q,x;
int solve(int x)
{
    int l=1,r=n,res=-1;
    while(l<=r)
    {
        int mid = (l+r)/2;
        if(a[mid]>=x)
        {
            res = mid;
            r = mid-1;
        }
        else{
            l = mid+1;
        }
    }
    return res;
    
} 
int main(){
    cin>>n;
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    cin>>q;
    while(q--)
    {
        cin>>x;
        int res = solve(x);
        if(res==-1){
            cout<<n+1<<endl;
        }
        else if(res==1){
            cout<<1<<endl;
        }
        else{
            cout<<res<<endl;
        }
    }
    return 0;
}
复制代码

 

 

3750: 二分查找

描述

 

将n个从小到大排序的整数(n<1000000)从1~n进行编号,并给出一个待查找的整数,请使用二分法进行查找。

 

 

 

输入

 

第一行为n(n<1000000)和m(m<100000),n表示序列中的元素个数,m表示查询次数。

第二行为n个从小到大排序的整数,以空格分隔;

接下来有m行,每行一个待查询的整数。

 

 

输出

 

对于每次查询,如果能够在序列中找到待查询的整数,则输出编号(如果存在多个编号,返回编号最小的),如果不存在,则输出None。

 

 

样例输入

 10 2

1 2 4 5 6 7 8 9 10 11

10

12

样例输出

 9

None

复制代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e6+10,inf = 0x3f3f3f3f;
int a[N];
int find(int x,int l,int r)
{
    while(l<r)
    {
        int mid = (l+r) / 2;
        if(a[mid] >= x)r = mid;
        else l = mid + 1;
    }
    return r;
}
int main()
{
    int n,m;
    cin >> n >> m;
    for(int i = 1;i <= n;i++)
        scanf("%d",&a[i]);
    sort(a + 1, a + 1 + n);
    while(m--)
    {
        int x;scanf("%d",&x);
        int id = find(x,1,n);
        if(a[id]==x)printf("%d\n",id);
        else puts("None");
    }
     return 0;
}
复制代码

 

 

7379: 二分查找II

描述

 

将n个从大到小排序的整数(n<1000000)从1~n进行编号,并给出一个待查找的整数,请使用二分法进行查找。

 

 

输入

 

第一行为n(n<1000000)和m(m<100000),n表示序列中的元素个数,m表示查询次数。

第二行为n个从大到小排序的整数,以空格分隔;

接下来有m行,每行一个待查询的整数。

 

 

输出

 

对于每次查询,如果能够在序列中找到待查询的整数,则输出编号(如果存在多个编号,返回编号最大的),如果不存在,则输出None。

 

 

样例输入

 

10 2
11 10 9 8 7 6 5 4 2 1
10
12

样例输出

2
None

 

复制代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e6+10,inf = 0x3f3f3f3f;
int a[N];
int n,m; 
void find(int x)
{
    int l = 1,r = n;
    while(l<=r)
    {
        int mid = (l+r)/2;
        if(a[mid]==x)
        {
            while(a[mid]==x)mid++;
            cout<<mid-1<<endl;
            return ;
        }
        else if(a[mid]>x)l = mid+1;
        else r = mid-1;
    }
    cout<<"None"<<endl;
    return;
}
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    for(int i=1;i<=m;i++)
    {
        int x;scanf("%d",&x);
        find(x);
    }
     return 0;
}
View Code
复制代码

 

7645: 查找最接近的元素

描述

 

在一个非降序列中,查找与给定值最接近的元素。

 

输入

 

第一行包含一个整数n,为非降序列长度。1≤n≤100000。

第二行包含n个整数,为非降序列各元素。所有元素的大小均在0−1,000,000,000之间。

第三行包含一个整数m,为要询问的给定值个数。1≤m≤10000。

接下来m行,每行一个整数,为要询问最接近元素的给定值。所有给定值的大小均在0~1,000,000,000之间。

 

 

输出

 

m行,每行一个整数,为最接近相应给定值的元素值,保持输入顺序。若有多个值满足条件,输出最小的一个。

 

样例输入

 

3
2 5 8
2
10
5

样例输出

 

8
5

复制代码
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n,a[1000010],q,x;
int solve(int x)
{
    int l=1,r=n,res=-1;
    while(l<=r)
    {
        int mid = (l+r)/2;
        if(a[mid]>=x)
        {
            res = mid;
            r = mid-1;
        }
        else{
            l = mid+1;
        }
    }
    return res;
    
} 
int main(){
    cin>>n;
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    cin>>q;
    while(q--)
    {
        cin>>x;
        int res = solve(x);
        if(res==-1){
            cout<<a[n]<<endl;
        }
        else if(res==1){
            cout<<a[1]<<endl;
        }
        else{
            if(x-a[res-1]<=a[res]-x)cout<<a[res-1]<<endl;
            else cout<<a[res]<<endl;
        }
    }
    return 0;
}
View Code
复制代码

 

7692: 查找元素

描述

 

在一个非降序列中,给定一个x,查找该元素值所在的位置。

 

 

输入

 

第一行包含一个整数n,为非降序列长度。1≤n≤100000。

第二行包含n个整数,为非降序列各元素。所有元素的大小均在0−1,000,000,000之间。

第三行包含一个整数m,为要询问的给定值个数。1≤m≤10000。

接下来m行,每行一个整数,为要询问的值x。所有给定值的大小均在0~1,000,000,000之间。

 

输出

 

如果存在输出该元素所在的位置。

如果不存在:

(1)如果序列中存在大于x的元素,则返回大于x且最接近的元素位置;

(2)如果序列中不存在大于x的元素,则返回最后一个元素后面的位置。

 

样例输入

 

3
2 5 8
3
10
5
6

样例输出

 

4
2
3

复制代码
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n,a[1000010],q,x;
int solve(int x)
{
    int l=1,r=n,res=-1;
    while(l<=r)
    {
        int mid = (l+r)/2;
        if(a[mid]>=x)
        {
            res = mid;
            r = mid-1;
        }
        else{
            l = mid+1;
        }
    }
    return res;
    
} 
int main(){
    cin>>n;
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    cin>>q;
    while(q--)
    {
        cin>>x;
        int res = solve(x);
        if(res==-1){
            cout<<n+1<<endl;
        }
        else if(res==1){
            cout<<1<<endl;
        }
        else{
            cout<<res<<endl;
        }
    }
    return 0;
}
View Code
复制代码

 

posted @   CRt0729  阅读(115)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示