bzoj 1336 && bzoj 1337 最小圓覆蓋 隨機增量法


題意:n個點,求出最小圓覆蓋,輸出半徑和坐標

最小圓覆蓋裸題...

蒟蒻只會隨機增量法...


bzoj 1336

type
        rec=record
            x,y:double;
end;

var
        n,x,y           :longint;
        a               :array[0..100010] of rec;
        i               :longint;
        c,ans           :rec;
        ans_r           :double;
function dis(p,q:rec):double;
begin
   exit(sqrt((p.x-q.x)*(p.x-q.x) + (p.y-q.y)*(p.y-q.y)));
end;

function get_yuanxin(o,p,q:rec):rec;
var
        a,b,c,d,e,f:double;
        ans:rec;
begin
   ans.x:=0; ans.y:=0;
   a:=2*(p.x-o.x); b:=2*(p.y-o.y); c:=p.x*p.x-o.x*o.x+p.y*p.y-o.y*o.y;
   d:=2*(q.x-p.x); e:=2*(q.y-p.y); f:=q.x*q.x-p.x*p.x+q.y*q.y-p.y*p.y;
   if (a*e-b*d<>0) then
   begin
      ans.x:=(c*e-b*f)/(a*e-b*d);
      ans.y:=(a*f-c*d)/(a*e-b*d);
   end;
   exit(ans);
end;

procedure work;
var
        i,j,k:longint;
        tt:rec;
        rr:double;
begin
   tt:=a[1]; rr:=0;
   for i:=2 to n do
     if (dis(a[i],tt)>rr) then
     begin
        rr:=0; tt:=a[i];
        for j:=1 to i-1 do
          if (dis(a[j],tt)>rr) then
          begin
             tt.x:=(a[i].x+a[j].x)/2;
             tt.y:=(a[i].y+a[j].y)/2;
             rr:=dis(a[j],tt);
             for k:=1 to j-1 do
               if dis(a[k],tt)>rr then
               begin
                  tt:=get_yuanxin(a[i],a[j],a[k]);
                  rr:=dis(tt,a[k]);
               end;
          end;
     end;
   ans_r:=rr;
   ans:=tt;
end;

begin
   read(n);
   for i:=1 to n do read(a[i].x,a[i].y);
   for i:=1 to 50000 do
   begin
      x:=random(n)+1; y:=random(n)+1;
      c:=a[x]; a[x]:=a[y]; a[y]:=c;
   end;
   work;
   writeln(ans_r:0:6);
   writeln(ans.x:0:6,' ',ans.y:0:6);
end.


bzoj 1337

type
        rec=record
            x,y:double;
end;

var
        n,x,y           :longint;
        i               :longint;
        a               :array[0..100010] of rec;
        ans_r           :double;
        c               :rec;
function dis(p,q:rec):double;
begin
   exit(sqrt((q.x-p.x)*(q.x-p.x)+(q.y-p.y)*(q.y-p.y)))
end;

function get_yuanxin(o,p,q:rec):rec;
var
        a,b,c,d,e,f:double;
        ans:rec;
begin
   ans.x:=0; ans.y:=0;
   a:=2*(p.x-o.x); b:=2*(p.y-o.y); c:=p.x*p.x+p.y*p.y-o.x*o.x-o.y*o.y;
   d:=2*(q.x-p.x); e:=2*(q.y-p.y); f:=q.x*q.x+q.y*q.y-p.x*p.x-p.y*p.y;
   if (a*e-b*d<>0) then
   begin
      ans.x:=(c*e-b*f)/(a*e-b*d);
      ans.y:=(a*f-c*d)/(a*e-b*d);
   end;
   exit(ans);
end;

procedure work;
var
        i,j,k:longint;
        tt:rec;
        rr:double;
begin
   tt:=a[1]; rr:=0;
   for i:=2 to n do
     if (dis(a[i],tt)>rr) then
     begin
        tt:=a[i]; rr:=0;
        for j:=1 to i-1 do
          if (dis(a[j],tt)>rr) then
          begin
             tt.x:=(a[i].x+a[j].x)/2;
             tt.y:=(a[i].y+a[j].y)/2;
             rr:=dis(tt,a[j]);
             for k:=1 to j-1 do
               if (dis(a[k],tt)>rr) then
               begin
                  tt:=get_yuanxin(a[i],a[j],a[k]);
                  rr:=dis(tt,a[k]);
               end;
          end;
     end;
   ans_r:=rr;
end;

begin
   read(n);
   for i:=1 to n do read(a[i].x,a[i].y);
   for i:=1 to 50000 do
   begin
      x:=random(n)+1; y:=random(n)+1;
      c:=a[x]; a[x]:=a[y]; a[y]:=c;
   end;
   work;
   writeln(ans_r:0:3);
end.
——by Eirlys



注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com