题目链接
题目大意
n个学生成绩,m个学校预计分数线,要求学校的预计分数线和学生的估分相差最小(可高可低),这个最小值为不满意度,求所有学生不满意度和的最小值。
思路
二分法,挑选与该学生分数差最小的数即可。由于预计分数与学生分数可高可低,所以要考虑相邻的两个数。
输入与输出样例
输入
4 3
513 598 567 689
500 600 550
输出
32
AC代码
代码一(手写二分)
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<math.h>
using namespace std;
const int maxn = 1e6 + 5;
int a[maxn], b[maxn];
int main(int argc, char* argv[])
{
int n, m;
scanf("%d%d", &m, &n);
for (int i = 0; i < m; ++i)scanf("%d", &a[i]);//学校分数线
for (int i = 0; i < n; ++i)scanf("%d", &b[i]);//学生成绩
sort(a, a + m);
sort(b, b + n);
int tot = 0;
for (int i = 0; i < n; ++i)
{
int l = 0, r = m;
int score = b[i];
while (l < r)
{
int mid = (l + r) / 2;
if (score <= a[mid]) {
r = mid;
}
else {
l = mid + 1;
}
}
//边界条件
if (l == 0) {
tot += abs(a[l] - score);
}
else tot += min(abs(a[l] - score), abs(a[l - 1] - score));
}
printf("%d\n", tot);
return 0;
}
代码二(STL:lower_bound)
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<math.h>
using namespace std;
const int maxn = 1e6 + 5;
int a[maxn];
int main(int argc, char* argv[])
{
int n, m;
scanf("%d%d", &m, &n);
for (int i = 0; i < m; ++i)scanf("%d", &a[i]);
sort(a, a + m);
int tot = 0;
for (int i = 0; i < n; ++i)
{
int score;
scanf("%d", &score);
int idx = lower_bound(a, a + m, score) - a;
if (idx == 0)tot += abs(a[idx] - score);
else tot += min(abs(a[idx - 1] - score), abs(a[idx] - score));
}
printf("%d\n", tot);
return 0;
}
代码三(优先队列)
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<math.h>
#include<queue>
using namespace std;
const int maxn = 1e6 + 5;
int a[maxn];
priority_queue<int, vector<int>, greater<int> >q;//优先队列,学生成绩
int main(int argc, char* argv[])
{
int n, m;
scanf("%d%d", &m, &n);
for (int i = 0; i < m; ++i)scanf("%d", &a[i]);
sort(a, a + m);
for (int i = 0; i < n; ++i)
{
int score;
scanf("%d", &score);
q.push(score);
}
int tot = 0 , idx = 0;
for (int i = 0; i < n; ++i)
{
int score = q.top(); q.pop();
int tmp = abs(a[idx]-score);
while (idx < m && abs(a[idx+1] - score) <= tmp)
{
idx++;
tmp = abs(a[idx] - score);
}
tot += tmp;
}
printf("%d\n", tot);
return 0;
}