试题 算法训练 Low Power
资源限制
内存限制:256.0MB C/C++时间限制:4.0s Java时间限制:12.0s Python时间限制:20.0s
问题描述
有n个机器,每个机器有2个芯片,每个芯片可以放k个电池。
每个芯片能量是k个电池的能量的最小值。
两个芯片的能量之差越小,这个机器就工作的越好。
现在有2nk个电池,已知它们的能量,我们要把它们放在n个机器上的芯片上,
使得所有机器的能量之差的最大值最小。
输入格式
第一行,两个正整数,n和k。
第二行,2nk个整数,表示每个电池的能量。
输出格式
一行一个整数,表示所有机器的能量之差的最大值最小是多少。
样例输入1
2 3
1 2 3 4 5 6 7 8 9 10 11 12
样例输出1
1
样例输入2
2 2
3 1 3 3 3 3 3 3
样例输出2
2
数据规模和约定
2nk <= 106, 1 <= pi <= 109。
分析
首先呢,这是一个求最大值的最小,满足单调性,那么就可以使用二分,快速缩小范围找到最小,这就确定使用二分了
然后就是关键就是说,每一个机器最主要的都必定是两个相邻的电池,然后就是写这个check函数了
ans代表已经确定了两个最小的机器的个数,那么那放进去的电池最多为ans * 2 * k,
i - 1代表已经使用的电池数,就是说已经使用了的不能大于当前能放进去的也就是要满足 i-1<=ans * 2 * k
也就是说绝对不可以 i - 1 > ans * 2 * k
然后就是满足条件的就可以放到一个新的机器上
举个例子
4 3
1 2 4 6 7 8 9 10 11 12 15
验证1是否可行
1 2满足那放到第一台机器
4 6不满足那把4放到第一台机器里
第一台机器就有 1 2 4
6 7满足就放到第二台机器里
接下来大家都知道了
那如果例子是
4 3
1 2 4 6 8 10 12 14 15。。。
那第一直无法确定第二台机器
可第一台机器最多装6个电池1 2 4 6 8 10
那12 14怎么办呢,开一个新的机器也不行,他俩就是当前最小的了,但是又不符合,对吧
代码
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
inline int max(int a, int b) { return a > b ? a : b; }
inline int min(int a, int b) { return a < b ? a : b; }
inline void read(int& x)
{
x = 0;
int f = 0;
char ch = getchar();
while (ch < '0' || ch > '9')
{
f |= (ch == '-');
ch = getchar();
}
while (ch >= '0' && ch <= '9')
{
x = (x << 1) + (x << 3) + (ch ^ 48);
ch = getchar();
}
x = f ? -x : x;
return;
}
const int N = 1e6 + 5;
int n, m, k;
int a[N];
//所有机器的能量之差的最大值为s行不行
int check(int s)
{
int ans = 0;
for (int i = 1; i < m; i++)
{
if (i - 1 > ans * 2 * k)return false;
if (a[i + 1] - a[i] <= s)
{
i++;
ans++;
}
if (ans == n)return true;
}
}
int main()
{
int s = 0;
read(n); read(k);
m = 2 * n * k;
for (int i = 1; i <= m; i++)read(a[i]);
sort(a + 1, a + 1 + m);
int left = 0, right = a[m], mid;
while (left <= right)
{
mid = (left + right) >> 1;
if (check(mid))
{
s = mid;
right = mid - 1;
}
else left = mid + 1;
}
cout << s;
return 0;
}