题目链接:P1678 烦恼的高考志愿 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)https://www.luogu.com.cn/problem/P1678
题目描述:
给出两组数据,遍历第二组每一个元素,在第一组数据中找到与之最接近的数,求他们的差。
对所有差求和,输出结果即可。
考虑到数据范围为1000000,如果两个for循环解题必定会超时。可以使用二分查找优化。
思路:
vector存储第二组数据,然后用sort排序,满足二分查找的先前条件。
while (m--)
{
int x;
cin >> x;
s.push_back(x);
}
sort(s.begin(), s.end());
先二分找到是否有与之相等的值,有直接continue;
两次二分分别找到离我最近且最小,最大的两个数,求出最小差。
AC代码:
#include <bits/stdc++.h>
using namespace std;
vector<int > s;
typedef long long LL;
int main()
{
int m, n;
cin >> m >> n;
LL ans = 0;
while (m--)
{
int x;
cin >> x;
s.push_back(x);
}
sort(s.begin(), s.end());
while (n--)
{
int x;
cin >> x;
int i, j;
//
int l = 0, r = s.size() - 1;
while (l < r)
{
int mid = l + r + 1 >> 1;
if (s[mid] <= x) l = mid;
else r = mid - 1;
}
if (s[l] != x)
{
i = abs(s[l] - x);
//
l = 0, r = s.size() - 1;
while (l < r)
{
int mid = l + r + 1 >> 1;
if (s[mid] < x) l = mid;
else r = mid - 1;
}
i = abs(s[l] - x);
//
l = 0, r = s.size() - 1;
while (l < r)
{
int mid = l + r >> 1;
if (s[mid] > x) r = mid;
else l = mid + 1;
}
j = abs(s[l] - x);
//
ans += min(i, j);
}
}
cout << ans;
return 0;
}