折半查找法,元素第一次出现的位置。
2413: C语言习题 折半查找
时间限制: 1 Sec 内存限制: 128 MB
提交: 12181 解决: 854
[提交][状态][讨论版][命题人:lyh]题目描述
有n个数(n<=1000000),这n个数已按从大到小顺序存放在一个数组中,然后有T次查询,每次输入一个数,要求用折半查找法找出该数在数组中第一次出现的位置。如果不在数组中输出0。
输入
第一行数组元素的个数n
第二行n个数组元素的值
第三行输入查询次数T (T<=100000)往下有T行,每行输入一个需要查询的数字
输出
查找的值在数组中的位置
样例输入
copy10 10 9 8 7 6 5 4 3 2 1 2 9 5
当时(上个学期期中)这个题挂掉了不少英雄好汉,期末考试这个题我也没做出来。
emmmm,现在看这个题很简单。
如果写对了折半查找,那么大部分人出错的原因应该就是忽略了他让你输出第一次出现的位置吧。
因为,折半查找,第一次找到的不一定是,该元素第一次出现的位置呀。
例如:1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 5 。让你找 元素1.但是第一次返回的下标肯定不是 1 呀。
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=1000005;
int arr[maxn];
bool cmp(int a,int b)
{
return a>b;
}
int b_search(int left,int right,int num)
{
while(left<=right)
{
// printf("&&&");
int mid=(left+right)/2;
if(arr[mid]<num) right=mid-1;
else if(arr[mid]>num) left=mid+1;
else if(arr[mid]==num)
{
if(arr[mid-1]==arr[mid]) return b_search(left,mid-1,num);
else return mid;
}
}
// printf("##");
return -1;
}
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&arr[i]);
sort(arr+1,arr+1+n,cmp);
int t;
scanf("%d",&t);
while(t--)
{
int num;
scanf("%d",&num);
int p=b_search(1,n,num);
if(p==-1) printf("0\n");
else printf("%d\n",p);
}
return 0;
}
这个题还有另外的方法,用STL里的 lower_bound( )函数。
这个函数也是基于二分查找的。返回的是 ,第一个不小于该元素的 迭代器。。
emmm,我还用的不太熟。