洛谷题单指南-二分查找与二分答案-P1678 烦恼的高考志愿

原题链接:https://www.luogu.com.cn/problem/P1678

题意解读:要计算不满意度之和的最小值,就要保证每个人的不满意度最小,即选择的学校录取分数-学生分数之差的绝对值最小。

解题思路:

如何在学校录取分数中找与学生分数最接近的呢?有三种可能:

1、学生分数在录取分数中存在相等的

2、学生分数在录取分数中不存在,找刚好比学生分数大的录取分数

3、学生分数在录取分数中不存在,找刚好比学生分数小的录取分数

正好可以对应二分的两种模版,

模版1:要么找到相等值,要么找到刚好大于学生分数的值

模版2:要么找到相等值,要么找到刚好小于学生分数的值

用两个二分计算之后,取录取分数-学生分数的绝对值较小的。

100分代码:

#include <bits/stdc++.h>
using namespace std;

const int M = 100005, N = 100005;

int a[M], b[N], m, n;
long long ans;

int bs1(int x)
{
    int l = 1, r = m, res = -1;
    while(l <= r)
    {
        int mid = (l + r) >> 1;
        if(a[mid] >= x) res = mid, r = mid - 1;
        else l = mid + 1;
    }
    return res;
}

int bs2(int x)
{
    int l = 1, r = m, res = -1;
    while(l <= r)
    {
        int mid = (l + r) >> 1;
        if(a[mid] <= x) res = mid, l = mid + 1;
        else r = mid - 1;
    }

    return res;
}

int main()
{
    cin >> m >> n;
    for(int i = 1; i <= m; i++) cin >> a[i];
    for(int i = 1; i <= n; i++) cin >> b[i];

    sort(a + 1, a + m + 1);

    for(int i = 1; i <= n; i++)
    {
        int idx1 = bs1(b[i]);
        int idx2 = bs2(b[i]);
        int v = INT_MAX;
        if(idx1 != -1) v = min(v, abs(a[idx1] - b[i]));
        if(idx2 != -1) v = min(v, abs(a[idx2] - b[i]));
        ans += v;
    }
    cout << ans;

    return  0;
}

 

posted @ 2024-02-29 18:15  五月江城  阅读(63)  评论(0编辑  收藏  举报