题目描述:
输入 n(n≤106) 个不超过 109 的单调不减的(就是后面的数字不小于前面的数字)整数 a1,a2,…,an,然后进行 m(m≤105) 次询问。
对于每次询问,给出一个整数 q(−109≤q≤109)
要求输出这个数字在序列中第一次出现的编号,如果没有找到的话输出 -1 。
话不多说,先上关键代码:
这是第一种方法
void erfen(int x,int m){
int l=1,r=m;//m为数组的长度;
while(l<r){ //缩右区间;
int mid=l+(r-l)/2;//注意,最好写成这样的格式;
if(a[mid]>=x) r=mid;
else l=mid+1;
}
//输出结果;
if(a[l]==x) cout<<l<<"\n";
else cout<<-1<<"\n";
}
由于数据量较大,可以采用快读(当然可以用scanf函数代替cin输出,printf函数代替cout输出):
int read(){
int x=0;
int f=1;
char c=getchar();
while(c<'0'||c>'9'){//注意两重判断
if(c=='-') f=-1;
c=getchar();
}
while(c>='0'&&c<='9'){
x=x*10+c-'0';
c=getchar();
}
return x*f;
}
接下来便是完整的代码:
#include<bits/stdc++.h>//万能头文件
using namespace std;
int n,m;
int a[1000090];
int read(){
int x=0;
int f=1;
char c=getchar();
while(c<'0'||c>'9'){
if(c=='-') f=-1;
c=getchar();
}
while(c>='0'&&c<='9'){
x=x*10+c-'0';
c=getchar();
}
return x*f;
}
void erfen(int x,int m){
int l=1,r=m;
while(l<r){
int mid=l+(r-l)/2;
if(a[mid]>=x) r=mid;
else l=mid+1;
}
if(a[l]==x) cout<<l<<"\n";
else cout<<-1<<"\n";
}
int main(){
cin>>m>>n;
for(int i=1;i<=m;i++) a[i]=read();
for(int i=1;i<=n;i++){
int x;
x=read();
erfen(x,m);
}
return 0;
}
接下来是第二种方法
先介绍两个函数:
int n;
cin>>n;
int a[n];
int x;
int x=lower_bound(a+1,a+n+1,x)-a //查找第一个大于或者大于x的数字的位置
int y=upper_bound(a+1,a+n+1,x)-a //查找第一个大于x的数字的位置
那么接下了的事情就简单了
请看代码:
#include<bits/stdc++.h>
using namespace std;
int n,m;
int a[1000050];
int read(){
int x=0;
int f=1;
char c=getchar();
while(c<'0'||c>'9'){
if(c=='-'){
f=-1;
}
c=getchar();
}
while(c>='0'&&c<='9'){
x=x*10+c-'0';
c=getchar();
}
return x*f;
}
void js(int x){
int pos=lower_bound(a+1,a+1+n,x)-a;
if(a[pos]==x) cout<<pos<<"\n";
else cout<<"-1\n";
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++) a[i]=read();
while(m--){
int x;
x=read();
js(x);
}
return 0;
}
如果有什么不解或者建议,请在评论区留言,感谢。