bzoj 1336 && bzoj 1337 最小圆覆盖 随机增量法

61 篇文章 0 订阅
3 篇文章 0 订阅

题意: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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值