题面
思路分析
对数据排序后进行二分查找即可。
代码实现
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
using namespace std;
int a[20000];
int cmp(const void *a,const void *b){
return (*(int*)a-*(int*)b);
}
int search(int x,int n){
int l=0,r=n-1,m=(l+r)/2;
while(1){
if(a[l]==x&&(a[l-1]!=x||l==0)) return l;
if(a[r]==x&&(a[r-1]!=x||r==0)) return r;
if(a[m]==x&&(a[m-1]!=x||m==0)) return m;
if(abs(l-r)<=1) return -1;
if(a[m]>x){
r=m;
}
else if(a[m]<x){
l=m;
}
else if(a[m]==x){
r=m;
}
m=(l+r)/2;
}
}
int main(){
//freopen("10474.out","w",stdout);
int n,q,t=0;
while(scanf("%d%d",&n,&q)!=EOF){
if(n==0&&q==0) return 0;
t++;
printf("CASE# %d:\n",t);
for(int i=0;i<n;i++) scanf("%d",&a[i]);
qsort(a,n,sizeof(a[0]),cmp);
int x;
for(int i=0;i<q;i++){
scanf("%d",&x);
int ans=search(x,n);
if(ans==-1) printf("%d not found\n",x);
else printf("%d found at %d\n",x,ans+1);
}
}
return 0;
}
早期代码,二分查找实现的十分丑陋
代码实现2
刘汝佳书中给出的代码,使用了STL中的lower_bound函数
知识点
快速排序函数sort
sort(a,a+n)中a与a+n实质是指向排序数组的指针,a为待排序数组的首位,a+n为待排序数组的末位的后一位。若排序对象为vector,则使用sort(v.begin(),v.end())来调用。
注意此类.end函数返回的也是容器末位的后一位。
默认从小到大排序,对于自定义类型的排序可添加返回值为bool类型的cmp函数。
二分查找函数
lower_bound(a,a+n,x):与sort类似,a为查找数组的首位,a+n为查找数组的末位的后一位,x为查找的元素,返回数组中大于等于x的第一个位置(返回值为一个指针)。
类似的,存在upper_bound和binary_search。
upper_bound(起始地址,结束地址,要查找的数值)
返回的是 第一个大于待查找数值 出现的位置。
binary_search(起始地址,结束地址,要查找的数值) 返回的是 是否存在这么一个数,是一个bool值。
同样,此类查找函数在vector中也适用。