第三题:
问题三:路由器安置(Routing)
【问题描述】
为备战灭日行动,我军需要在一条战道上安装通讯装置,现在需要搭建的是我军独有技术的无线网络(频率为敌军无法捕捉到的),需要放置M个路由器。整条战道上一共有N个军事基地,分布在一条接近直线的线上,每一个基地必须被至少一台路由器覆盖到。现在的问题是所有路由器的覆盖半径是一样的,我军希望用覆盖半径尽可能小的路由器来完成任务,因为这样可以节省成本。
【输入数据】
输入文件第一行包含两个整数M和N,以下N行每行一个整数Hi表示该基地在战道上相对于某个点的坐标。
【输出数据】
输出文件仅包含一个数,表示最小的覆盖半径,保留一位小数。
【样例输入】
2 3
1
3
10
【样例输出】
1.0
【数据规模】
对于60%的数据,有1 ≤ N, M ≤ 100,-1000 ≤ Hi ≤ 1000;
对于100%的数据,有1 ≤ N, M ≤ 100000,-10000000 ≤ Hi ≤ 10000000。
首先,朴素的枚举肯定会超时,可以二分
program exam;
var
i,j,k,l,m,n,max,min,mid:longint;
ansl:real;
a:array[1..10] of longint;
b:array[1..10] of boolean;
procedure sort(l,r: longint);
var
i,j,x,y: longint;
begin
i:=l;
j:=r;
x:=a[(l+r) div 2];
repeat
while a[i]<x do
inc(i);
while x<a[j] do
dec(j);
if not(i>j) then
begin
y:=a[i];
a[i]:=a[j];
a[j]:=y;
inc(i);
j:=j-1;
end;
until i>j;
if l<j then
sort(l,j);
if i<r then
sort(i,r);
end;
function try(len:longint):longint;
var
i,j,k,head,tail:longint;
begin
head:=1;
tail:=1;
k:=m;
dec(k);
repeat
if head=tail then
tail:=head+1;
if a[tail]-a[head]<=2*len then
inc(tail);
if a[tail]-a[head]>2*len then
begin
head:=tail;
dec(k);
end;
until tail>=n;
try:=k;
if k>=0 then
ansl:=len/2;
{fillchar(b,sizeof(b),false);// 错误思路,只考虑到一或二个基地
k:=m;
for i:=2 to n do
begin
if i<n then
begin
if (a[i+1]-a[i-1]<=len) and (b[i-1]=false) and (b[i]=false) and (b[i+1]=false) then
begin
b[i-1]:=true;
b[i]:=true;
b[i+1]:=true;
k:=k+2;
end;
if (a[i]-a[i-1]<=2*len) and (b[i]=false) and (b[i-1]=false) then
begin
b[i-1]:=true;
b[i]:=true;
inc(k);
end;
end;
if i=n then
if (a[i]-a[i-1]<=2*len) and (b[i]=false) and (b[i-1]=false) then
begin
b[i-1]:=true;
b[i]:=true;
inc(k);
end;
end;
try:=k;
if k>=n then
ansl:=len / 2;}
end;
begin
assign(input,'routing.in');
reset(input);
assign(output,'routing.out');
rewrite(output);
readln(m,n);
if m>=n then
begin
writeln('0.0');
halt;
end;
for i:=1 to n do
begin
readln(k);
a[i]:=k*2;
//readln(a[i]);
end;
sort(1,n);
max:=a[n]-a[1];
min:=0;
mid:=(max+min) div 2;
repeat
if try(mid)>=0 then
max:=mid
else
min:=mid;
mid:=(min+max) div 2;
if min=mid then
if try(min)>=0 then
max:=min
else
min:=max;
until min=max;
writeln(ansl:0:1);
close(input);
close(output);
end.