福建工程大学OJ --- 2570 university 【二分 , lower_bound 的运用】

传送门
//对于每一个学生的分数, 找和该分数最近的学校即可.
//当然用二分找啊, 然后如果熟练运用了lower_bound 和 upper_bound(下面会详细介绍介绍) , 那么直接上就可以, 否则你就直接手写这两个函数(xx, 博主不是很会手写哎,大概知道一些 )也是可以的. 注意边界条件! 即第0个学校就另成一个极值, 反正就是如果没有符合的, 就选边界.

AC Code : (lower_bound 写法)

/** @Cain*/
const int maxn=1e5+5;
int m,n;
int a[maxn],b[maxn];
void solve()
{
    while(~scanf("%d%d",&m,&n)){
        for(int i=1;i<=m;i++) scanf("%d",&a[i]);
        for(int i=1;i<=n;i++) scanf("%d",&b[i]);
        a[0] = -inf, a[m+1] = inf;  //特别注意边界条件.
        sort(a,a+2+m);
        ll res = 0;
        for(int i=1;i<=n;i++){
            int tmp = lower_bound(a+1,a+1+m,b[i])-a;
            res += min(abs(a[tmp-1] - b[i]),abs(a[tmp] - b[i]));
        }
        printf("%lld\n",res);
    }
}

1:lower_bound【返回第一个大于等于要查找的数的下标位置!】
例 :
//如果是单纯的找我们要找的值的话, 都是减的数组首地址, 不管是什么下标开头, 返回的值, 该怎么用就怎么用.
//但是在离散化里面用的话还是有一点不一样, 因为要看你愿意让下标从什么开头, 总之用的时候根据题意的要求适当的画一画, 然后在写!!!

/** @Cain*/
#include <bits/stdc++.h>
using namespace std;
int n;
int a[10] = {1,2,3,5,6,7,8,9};
int main()
{
    while(~scanf("%d",&n)){
        int pos = lower_bound(a,a+8,n)-a;
        cout << pos << endl;
    }
}

手写: (所以上面那么换成手写的也是可以, 我就不写了)

/** @Cain*/
#include <bits/stdc++.h>
using namespace std;
int n;
int a[10] = {0,5,6,7,8,9,513,567,600};
int main()
{
    while(~scanf("%d",&n)){
        int l =1,r =8,mid;
        while(r-l>0){
            mid = (r+l) >> 1;
            if(a[mid] >= n) r = mid ;
            else l = mid + 1 ;
        }
        printf("%d %d\n",l,a[l]);
    }
}

2:upper_bound【返回第一个小于等于要查找的数的下标位置!】 和lower_bound类似, 就不多说了.
只有在要被查找的数组里有重复元素的时候这两个函数有点区别.

//个人觉得, 既然有函数, 那就用函数啊, 写的又快, 又能减少错误, 为什么不用了?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值