[C++] AcWing 789. 数的范围

前言


只是记录

这道题是二分查找

什么是二分查找?

简述:查找的时候把序列一分为二,每次都把要找的数 (a) 和序列中间那个数 (b) 比,如果a>b,就从 b 的后面开始找;如果a<b,就从b的前面开始找(找的时候也是从这样一分为二,跟中间的数比较)。为什么可以找呢?因为二分查找必须是在有序的数组里找。有序性就决定了,如果a>b,那么b前面的数都<a,要找的数在b后面;a<b同理。

题目


模板


整数二分查找

/*检查x是否满足某种性质*/
bool check(int x){/*...*/}

/*[l,r] => [l,mid],[mid+1,r]*/
int Search_L(int l,int r)
{//查找左边界(边界最左边那个数)
    while(l<r)
    {
        int mid=l+r>>1;
        if(check(mid))
            r=mid;
        else
            l=mid+1;
    }
    return l;
}
/*[l,r] => [l,mid-1],[mid,r]*/
int Search_R(int l,int r)
{//查找右边界(边界最右边那个数)
    while(l<r)
    {
        int mid=l+r+1>>1;//需要+1,防止死循环
        if(check(mid))
            l=mid;
        else
            r=mid-1;
    }
    return l;
}
  • 每次使用这两个模板的时候,先想是找这个区间的左端点还是右端点,然后选择使用模板,最后再去写判断条件。

思路


输入样例

1 2 2 3 3 4

假如,查找3,但是有重复的,因此需要划分左右边界 | 3  3 |,查找左边界的3,用Search_L模板,查找右边界的3,用Search_R模板。

代码

#include<bits/stdc++.h>
using namespace std;
const int N=100010;
int a[N];
int n,q,k;
int SL(int l,int r,int k)
{
	while(l<r)
	{
		int mid=l+r>>1;
		if(a[mid]>=k)
			r=mid;
		else
			l=mid+1;
	}
	return l;
}
int SR(int l,int r,int k)
{
	while(l<r)
	{
		int mid=l+r+1>>1;
		if(a[mid]<=k)
			l=mid;
		else
			r=mid-1;
	}
	return l;
}
int main()
{
	cin>>n>>q;
	for(int i=0;i<n;i++)
		cin>>a[i];
	while(q--)
	{
		cin>>k;
		int l=SL(0,n-1,k);
		int r=SR(0,n-1,k);
		if(a[l]!=k)
			cout<<-1<<" ";
		else
			cout<<l<<" ";
		if(a[r]!=k)
			cout<<-1<<endl;
		else
			cout<<r<<endl;
	}
	return 0;
}

题目链接

https://www.acwing.com/problem/content/791/

参考

https://cpt1024.blog.csdn.net/article/details/123905773

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值