题目背景
计算机竞赛小组的神牛 V 神终于结束了高考,然而作为班长的他还不能闲下来,班主任老 t 给了他一个艰巨的任务:帮同学找出最合理的大学填报方案。可是 v 神太忙了,身后还有一群小姑娘等着和他约会,于是他想到了同为计算机竞赛小组的你,请你帮他完成这个艰巨的任务。
题目描述
现有 m 所学校,每所学校预计分数线是 ai。有 n 位学生,估分分别为 bi。
根据 nn 位学生的估分情况,分别给每位学生推荐一所学校,要求学校的预计分数线和学生的估分相差最小(可高可低,毕竟是估分嘛),这个最小值为不满意度。求所有学生不满意度和的最小值。
输入格式
第一行读入两个整数 m,n。m 表示学校数,n 表示学生数。
第二行共有 m 个数,表示 m 个学校的预计录取分数。第三行有 n 个数,表示 n 个学生的估分成绩。
输出格式
输出一行,为最小的不满度之和
题目分析:
这个题看起来是用来计算两个数组中元素之间的最小绝对差的总和。程序的主要步骤如下:
- 对数组 进行快速排序。
- 定义一个计数器,然后遍历数组 中的每个元素,找到它在数组 中的位置,并计算与其最近的三个元素的绝对差中的最小值,累加到 计数器中。
- 最后输出计数器。
在写代码时,我们还需要注意以下几点:
- 程序中使用的快速排序算法需要谨慎检查边界条件,以确保不会出现数组越界的情况。
- 在查找 数组中的位置时,采用了二分查找的方法。
- 计算与目标值的最小绝对差时,考虑了目标值左右相邻的两个元素
题目代码:
#include<cstdio>
#include<algorithm>
using namespace std;
int m, n;
int a[100000];
int b[100000];
int l, r, mid;
long long ans;
void qsort(int l, int r)
{
int i, j, p, mid;
i = l; j = r; mid = a[(l + r) / 2];
do
{
while (a[i] < mid) i++;
while (a[j] > mid) j--;
if (i <= j)
{
p = a[i]; a[i] = a[j]; a[j] = p;
i++; j--;
}
} while (i <= j);
if (l < j) qsort(l, j);
if (i < r) qsort(i, r);
}
int main()
{
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]);
qsort(1, m);
a[0] = -10000000;
for (int i = 1; i <= n; i++)
{
l = 1; r = m;
while (l < r)
{
mid = (l + r) / 2;
if (b[i] > a[mid])
l = mid + 1;
else
r = mid;
}
ans += min(abs(b[i] - a[l]), min(abs(b[i] - a[l - 1]), abs(b[i] - a[l + 1])));
}
printf("%lld", ans);
}