二分板子
Posted jiamian
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二分板子相关的知识,希望对你有一定的参考价值。
Description
用有序表表示静态查找表时,通常检索函数可以用折半查找来实现。
折半查找的查找过程是:首先确定待查记录所在的范围,然后逐步缩小范围直到找到或者确定找不到相应的记录为止。而每次需要缩小的范围均为上一次的一半,这样的查找过程可以被称为折半查找。
其查找过程可以描述如下:
在本题中,读入一串有序的整数,另外给定多次查询,判断每一次查询是否找到了相应的整数,如果找到则输出整数相应的位置。
Input
输入的第一行包含2个正整数n和k,分别表示共有n个整数和k次查询。其中n不超过1000,k同样不超过1000。
第二行包含n个用空格隔开的正整数,表示n个有序的整数。输入保证这n个整数是从小到大递增的。
第三行包含k个用空格隔开的正整数,表示k次查询的目标。
Output
只有1行,包含k个整数,分别表示每一次的查询结果。如果在查询中找到了对应的整数,则输出其相应的位置,否则输出-1。
请在每个整数后输出一个空格,并请注意行尾输出换行。
Sample Input
8 3 1 3 5 7 8 9 10 15 9 2 5
Sample Output
5 -1 2
HINT
在本题中,需要按照题目描述中的算法完成折半查找过程。通过将需要查询的值与当前区间中央的整数进行比较,不断缩小区间的范围,直到确定被查询的值是否存在。
通过课本中的性能分析部分,不难发现折半查找的时间复杂度为O(log2n),这是一种非常高效的查找方法。
如果序列为单调递增序列:
1 #include <stdio.h> 2 #include <string.h> 3 #include <iostream> 4 #include <string> 5 #include <math.h> 6 #include <algorithm> 7 #include <vector> 8 #include <queue> 9 #include <set> 10 #include <stack> 11 #include <map> 12 #include <sstream> 13 const int INF=0x3f3f3f3f; 14 typedef long long LL; 15 const int mod=1e9+7; 16 const int maxn=1e5+10; 17 using namespace std; 18 19 int a[1005]; 20 21 int main() 22 { 23 int n,m; 24 scanf("%d %d",&n,&m); 25 for(int i=0;i<n;i++) 26 scanf("%d",&a[i]); 27 for(int i=0;i<m;i++) 28 { 29 int x; 30 scanf("%d",&x); 31 int l=0; 32 int r=n-1; 33 int mid; 34 int flag=0; 35 while(l<=r) 36 { 37 mid=(l+r)>>1; 38 if(a[mid]==x) 39 { 40 flag=1; 41 break; 42 } 43 else if(a[mid]>x) 44 r=mid-1; 45 else 46 l=mid+1; 47 } 48 if(flag==1) 49 printf("%d ",mid); 50 else 51 printf("-1 "); 52 } 53 printf(" "); 54 return 0; 55 }
如果序列为单调非递减序列(有重复值):
#include <stdio.h> #include <string.h> #include <iostream> #include <string> #include <math.h> #include <algorithm> #include <vector> #include <queue> #include <set> #include <stack> #include <map> #include <sstream> const int INF=0x3f3f3f3f; typedef long long LL; const int mod=1e9+7; const int maxn=1e5+10; using namespace std; int a[1005]; int main() { int n,m; scanf("%d %d",&n,&m); for(int i=0;i<n;i++) scanf("%d",&a[i]); for(int i=0;i<m;i++) { int x; scanf("%d",&x); int l=0; int r=n-1; int mid; while(l<r) { mid=(l+r)>>1; if(a[mid]<x) l=mid+1; else r=mid; } if(a[l]==x) printf("%d ",l); else printf("-1 "); } printf(" "); return 0; }
以上是关于二分板子的主要内容,如果未能解决你的问题,请参考以下文章