路由器安置

第三题:

问题三:路由器安置(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.

原文地址:https://www.cnblogs.com/fengxiudong/p/6017297.html