主题:二分查找最右值
请在一个有序不递减的数组中(数组中的值有相等的值),采用二分查找找到最后1次出现值x的位置,如果不存在x请输出-1。
#include<bits/stdc++.h>
using namespace std;
const int N = 1e6+5;
int n;
int a[N];
int solve(int x) {
int l = 1, r = n + 1, mid;
while(①) {
②
if(a[mid] < x)
③
else if(a[mid] == x)
④
else
r = mid;
}
int pos = ⑤;
if(a[pos] == x)
return pos;
else
return -1;
}
int main(){
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
int t;
cin>>t;
while(t--) {
int x;
cin>>x;
cout<<solve(x)<<" ";
}
}
选择题
1.①处应填()
A. l < r
B. l <= r
c. l == r
D. l != r-1
2.②处应填()
A. mid = l + r / 2;
B. mid = (l + r) >> 2;
C. mid = (r - l) / 2;
D. mid = l + r >> 1;
3.③处应填()
A. l = mid;
B. l = mid + 1;
C. r = mid;
D. r = mid - 1;
4.④处应填()
A. l = mid;
B. l = mid + 1;
C. r = mid;
D. r = mid - 1;
5.③处应填()
A. l
B. r
C. l + 1
D. r - 1
1.A 因为r赋值为n+1,而数组的范围是1~n,所以二分范围是l<r
2.D A加上括号为:l+(r/2);B扩展为:(l+r)/(2^2)=(l+r)/4;C没有道理;D:扩展为(l+r)/(2^1)=(l+r)/2
3.B 如果a[mid]<x,因为数列单调不降,所以答案应该在右侧,往右侧二分需要动左指针,l=mid+1
4.B 如果a[mid]==x,说明找到了,但题目要求找最右边的,所以应该继续往右侧二分,l=mid+1
5.D 可以模拟一个例子:在[1,2,4,4,7]中查找最后一个4
1) l=1,r=5 mid=3 a[3]=4->a[mid]==x l=mid+1=4
2) l=4,r=5 mid=4 a[4]=4->a[mid]==x l=mid+1=5
此时l==r,退出
发现此时的答案4,对应的位置是l-1或r-1,选项里只有r-1,所以只能选D
End
这里是 YLCHUP,谢谢大家!