二分查找——C++中lower_bound函数和upper_bound函数

二分查找
在一个排好序的数组中查找;
函数lower_bound()在first和last中的前闭后开区间进行二分查找,返回大于或等于val的第一个元素位置。如果所有元素都小于val,则返回last的位置

函数upper_bound()在first和last中的前闭后开区间进行二分查找,返回大于val的第一个元素位置。如果所有元素都小于val,则返回last的位置

lower_bound的源代码

int lower(LL *a,LL n,LL x){
	LL l=0,r=n-1;
	LL m;
	while(l<r){
		m=(l+r)/2;
		if(a[m]<x) l=m+1;
		else r=m;
	}
	if(a[l]>=x) return l;
	else return -1;
}

upper_bound源代码;

  int upper(LL *a,LL n,LL x){
	LL l=0,r=n-1;
	LL m;
	while(l<r){
		m=(l+r)/2;
		if(a[m]<=x) l=m+1;
		else r=m;
	}
	if(a[l]>x) return l;
	else return n;
}

如果你想找看一道用二分做的题目 请点here

#include <cstdio>
#include <algorithm>
#include <iostream>
#define LL long long
using namespace std;
const int maxn=100017;
LL s[maxn],p[maxn],c[maxn];
int lower(LL *a,LL n,LL x){
	LL l=0,r=n-1;
	LL m;
	while(l<r){
		m=(l+r)/2;
		if(a[m]<x) l=m+1;
		else r=m;
	}
	if(a[l]>=x) return l;
	else return -1;
}
int upper(LL *a,LL n,LL x){
	LL l=0,r=n-1;
	LL m;
	while(l<r){
		m=(l+r)/2;
		if(a[m]<=x) l=m+1;
		else r=m;
	}
	if(a[l]>x) return l;
	else return n;
}
int main()
{
    int T;
    int n, m;
    LL tt;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m);
        for(int i = 0; i < n; i++)
        {
            scanf("%lld%lld",&s[i],&p[i]);
        }

        LL minn = 9999999999999999;
        for(int i = n-1; i >= 0; i--)
        {
            minn = min(s[i]*p[i],minn);
            c[i] = minn;
        }
        for(int i = 0; i < m; i++)
        {
            scanf("%lld",&tt);
            if(tt>=s[n-1])//最后
                printf("%lld\n",tt*p[n-1]);
            else
            {
                int pos=upper(s,n,tt);
                LL ans = tt*p[pos-1];
                ans = min(ans,c[pos]);
                printf("%lld\n",ans);
            }
        }
    }
    return 0;
}

用函数的方式;

#include <cstdio>
#include <algorithm>
#include <iostream>
#define LL long long
using namespace std;
const int maxn=100017;
LL s[maxn],p[maxn],c[maxn];
int main()
{
    int T;
    int n, m;
    LL tt;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m);
        for(int i = 0; i < n; i++)
        {
            scanf("%lld%lld",&s[i],&p[i]);
        }

        LL minn = 9999999999999999;
        for(int i = n-1; i >= 0; i--)
        {
            minn = min(s[i]*p[i],minn);
            c[i] = minn;
        }
        for(int i = 0; i < m; i++)
        {
            scanf("%lld",&tt);
            if(tt>=s[n-1])//最后
                printf("%lld\n",tt*p[n-1]);
            else
            {
                int pos = upper_bound(s,s+n,tt)-s;
                LL ans = tt*p[pos-1];
                ans = min(ans,c[pos]);
                printf("%lld\n",ans);
            }
        }
    }
    return 0;
}

全部评论

相关推荐

秋招进行到现在终于能写总结了。完全没想到战线会拉这么长,过程会如此狼狈,不过更应该怪自己太菜了。好在所有的运气都用在了最后,也是有个去处。背景:双2本硕科班,无竞赛,本科一段研究所实习,硕士一段大厂暑期实习但无转正。技术栈是C++&nbsp;&amp;&nbsp;Golang,实习是客户端音视频(而且是鸿蒙端开发),简历两个C++项目一个Golang项目。主要投递岗位:后端,cpp软开,游戏服务端,测开,以及一些不拘泥于Java的岗位。从8月起总共投递123家公司,笔试数不清了,约面大约30家。offer/oc/意向:友塔游戏(第一个offer,面试体验很好,就是给钱好少南瑞继保(计算机科班点击就送(限男生),不...
乡土丁真真:佬很厉害,羡慕~虽然我还没有到校招的时候,也想讲一下自己的看法:我觉得不是CPP的问题,佬的背书双2,技术栈加了GO,有两段实习。投了123,面了30.拿到11个offer。这个数据已经很耀眼了。这不也是CPP带来的吗?当然也不止是CPP。至少来说在这个方向努力过的也会有好的结果和选择。同等学历和项目选java就会有更好的吗?我个人持疑问态度。当然CPP在方向选择上确实让人头大,但是我觉得能上岸,至于最后做什么方向,在我看来并不重要。至于CPP特殊,有岗位方向的随机性,java不是不挑方向,只是没得选而已。也希望自己以后校招的时候能offer满满
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务