二分查找
二分查找是一种在有序数组中查找特定元素的算法。它的基本思想是将数组分成两部分,判断目标元素在哪一部分中,然后继续在该部分中进行查找,直到找到目标元素或者确定目标元素不存在为止。这种算法的时间复杂度为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; }
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; }
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; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现