描述
一条街道安装无线网络,需要放置M个路由器。整条街道上一共有N户居民,分布在一条直线上,每一户居民必须被至少一台路由器覆盖到。现在的问题是所有路由器的覆盖半径是一样的,我们希望用覆盖半径尽可能小的路由器来完成任务,因为这样可以节省成本。(1 ≤ N, M ≤ 100000).
解法
典型二分。尝试当前路由器覆盖范围能否覆盖所有居民点,但会出现实数,因此·可以使用二分直径的方法, 最后实数折半输出.
return l * 1.0 / 2;
需要注意,输入数据可能是无序的(被坑了),因此输入后最好排下序。
部分代码
typedef long long LL;
LL m, n;
LL a[110000];
bool check(LL w)
{
LL temp1 = 0, temp2 = 1;
while ((temp1 = upper_bound(a, a + n, a[temp1] + w) - a) < n)
{
if (++temp2 > m)
{
return 0;
}
}
return 1;
}
double find()
{
LL l = 0, r = a[n - 1] - a[0];
while (l < r)
{
LL mid = (l + r) / 2;
if (check(mid))
{
r = mid;
}
else
{
l = mid + 1;
}
}
return l * 1.0 / 2;
}