[背景]
抓紧时间写完!
今天耗费VHOS心力最多的是这道虚伪的题目,首先必须要吐槽一下:为什么WIFI设置这么坑!!!!
好的,由于我们上的是分治,所以我优先选择了二分来做这道题,同时给出周神的递增版本。
[题目]
题目描述
一条街道安装WIFI,需要放置M个路由器。整条街道上一共有N户居民,分布在一条直线上,每一户居民必须被至少一台路由器覆盖到。现在的问题是所有路由器的覆盖半径是一样的,我们希望用覆盖半径尽可能小的路由器来完成任务,因为这样可以节省成本。
输入格式
输入文件第一行包含两个整数M和N,以下N行每行一个整数Hi表示该户居民在街道上相对于某个点的坐标。
输出格式
输出文件仅包含一个数,表示最小的覆盖半径,保留一位小数。
样例数据
input
2 3
1
3
10
output
1.0
数据规模与约定
时间限制:1s
1s
空间限制:256MB
256MB
注释
对于60%的数据,有1 ≤ N, M ≤ 100,-1000 ≤ Hi ≤ 1000; 对于100%的数据,有1 ≤ N, M ≤ 100000,-10000000 ≤ Hi ≤ 10000000。
[二分的分析]
很显然这道题要枚举最合适的路由器范围直径(然后除以二出答案)
而枚举的任务就交给枚举的代码了;
以上是程序的准备模块
很好,二分的主体完成了,现在只要判断这个直径值成不成立就行了;
虚伪虚伪虚伪虚伪,严重怀疑网络稳定性
[code]
[二分]
#include<bits/stdc++.h>
const int maxn=1<<17;
int lc[maxn]={};
int home=0,max_wifi=0;
int ip(void)
{
int sign=1,num=0;
char c=getchar();
for(;c<'0'||c>'9';c=getchar())
if(c=='-')
sign=-1;
for(;c>='0'&&c<='9';c=getchar())
num=(num<<1)+(num<<3)+c-'0';
return num*sign;
}
bool check(int size)
{
int wifi=0;
int left=1,right=1;
while(right<=home)
{
while(lc[right]-lc[left]<=size&&right<=home)
right++;
left=right;
wifi++;
}
if(wifi<=max_wifi)
return true;
else
return false;
}
int main(void)
{
max_wifi=ip();
home=ip();
for(int i=1;i<=home;i++)
{
lc[i]=ip();
}
std::sort(lc+1,lc+home+1);
int left=-1<<22;
int right=1<<22;
int mid=0;
while(left+1<right)
{
mid=(left+right)>>1;
if(check(mid))
right=mid;
else
left=mid;
}
if(check(left))
printf("%.1f",left*1.0/2);
else
printf("%.1f",right*1.0/2);
return 0;
}
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cctype>
const int maxn=1<<17;
int lc[maxn]={};
int home=0,max_wifi=0;
inline int ip(void)
{
register bool sign=false;
register char ip='#';
while(!isdigit(ip=getchar()))
sign|=(ip=='-');
register int op=(ip^'0');
while(isdigit(ip=getchar()))
op=(op<<3)+(op<<1)+(ip^'0');
return sign?~op+1:op;
}
bool check(int size)
{
int wifi=0;
int left=1,right=1;
while(right<=home)
{
while(lc[right]-lc[left]<=size&&right<=home)
right++;
left=right;
wifi++;
}
return (wifi<=max_wifi);
}
int main(void)
{
max_wifi=ip();
home=ip();
for(int i=1;i<=home;i++)
{
lc[i]=ip();
}
std::sort(lc+1,lc+home+1);
int answer=lc[home]-lc[1];
for (int i=log2(answer);i>=0;i--)
answer-=(1<<i)*(answer-(1<<i)>0&&check(answer-(1<<i)));
printf("%.1f",answer*1.0/2);
return 0;
}