二分查找
基本思路
基本思路就是左边界右边界,注意特殊情况,然后如果猜大了就把右边界设置为猜的-1,小了左边界为其+1即可。
AcWing 789. 数的范围
#include<stdio.h>
void query(int P[100100], int k, int n){
int l,r,p,f;
f=0;
l = 0, r = n-1;
while(l<=r){//边界条件是l不大于r
p = (l+r)>>1;
if(P[p]<k){
l = p+1;//更新边界的方式是不要带上p,直接收缩
}else if(P[p]>k){
r = p-1;//同上
}else{
f=1;
break;
}
}
if(f==0){
printf("-1 -1\n");
return;
}
//找边界也要二分,神人,从0和最大二分呗
//找左边界,性质是p+1是另一个
int left, right;
l = 0, r = p;
while(l<=r){
left = (l+r)>>1;
if(P[left]<P[p]){
l = left+1;
}else if(P[left-1]==P[p]){
r = left - 1;
}else{
break;
}
}
l = p, r = n - 1;
while(l<=r){
right = (l+r)>>1;
if(P[right+1]==P[p]){
l = right+1;
}else if(P[right]>P[p]){
r = right-1;
}else{
break;
}
}
printf("%d %d\n",left,right);
return;
}
int main(){
int n,q,P[100100],K[10010];
scanf("%d %d",&n,&q);
for(int i = 0; i < n; i++)scanf("%d",&P[i]);
for(int i = 0; i < q; i++)scanf("%d",&K[i]);
for(int i = 0; i < q; i++)query(P,K[i],n);
return 0;
}
AcWing 790. 数的三次方根
#include<stdio.h>
void get(double n){
double l,r,p,x;
if(n>1){
l = 0, r = n;
}else if(n < -1){
l = n, r = 0;
}else if(n>0&&n<1){
l = 0, r = 1;
}else if(n<0&&n>-1){
l = -1, r = 0;
}
while(l<=r){
p = (l+r)/2;
x = p*p*p;
if(x>n){
r = p - 0.0000001;
}else if(x<n){
l = p + 0.0000001;
}else{
break;
}
}
printf("%.6f",p);
}
int main(){
double n;
scanf("%lf",&n);
get(n);
return 0;
}