题目描述
输入 个不超过
的单调不减的(就是后面的数字不小于前面的数字)非负整数
,
然后进行
次询问。对于每次询问,给出一个整数
,要求输出这个数字在序列中第一次出现的编号,如果没有找到的话输出
。
数据分析
输入
11 3 1 3 3 3 5 7 9 11 13 15 15 1 3 6
输出
1 2 -1
第1行的11表示有11个数,3表示有3次询问。我们拿第2次询问来举例子,想要查找3,查到了多个3,输出就取第一个3的位置,输出2。
解法分析
用暴力(从第一个元素开始一个一个去查找)的算法复杂度为,会超时。我们用二分查找,每次缩小一半的查找范围,算法复杂度为
。但是这样做你会发现输出的是1 3 -1。这是因为题目要求找到第一次出现的编号,我们用while循环往前找到第一个值即可。另外要注意的一点是,要用scanf和printf输入输出数据,否则也会超时。
代码
#include<bits/stdc++.h>
using namespace std;
int n,m,q,a[1000005];
int find(int x){
int l=1,r=n;
while(l<r){
int mid=l+(r-l)/2;
if(a[mid]>=x) r=mid;
else l=mid+1;
}
if(a[l]==x)return l;
else return -1;
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
for(int i=1;i<=m;i++){
scanf("%d",&q);
int ans=find(q);
printf("%d ",ans);
}
return 0;
}
如有错误,欢迎大家指正补充。