bzoj2823

最小圆覆盖

有个东西叫作随机增量法,具体可以baidu

这里来说说怎么求三点共圆

这其实就是求两条线段的交点

在编程中,我们解方程是比较麻烦的一个比较好的方法是利用相似三角形

设线段AB,CD交P,则PC:PD=Sabc:Sabd

然后用定比分点就可以求的交点坐标了

 1 const eps=1e-6;
 2
 3 type point=record
 4        x,y:double;
 5      end;
 6
 7 var p:array[0..500010] of point;
 8     i,n,j,k:longint;
 9     r:double;
10
11 procedure swap(var a,b:point);
12   var c:point;
13   begin
14     c:=a;
15     a:=b;
16     b:=c;
17   end;
18
19 function dis(i,j:longint):double;
20   begin
21     exit(sqrt(sqr(p[i].x-p[j].x)+sqr(p[i].y-p[j].y)));
22   end;
23
24 function cov(i:longint):boolean;
25   begin
26     if dis(i,0)-r>eps then exit(false)
27     else exit(true);
28   end;
29
30 procedure little(i,j:longint);
31   begin
32     p[0].x:=(p[i].x+p[j].x)/2;
33     p[0].y:=(p[i].y+p[j].y)/2;
34     r:=dis(i,j)/2;
35   end;
36
37 function cross(x1,y1,x2,y2:double):double;
38   begin
39     exit(x1*y2-x2*y1);
40   end;
41
42 procedure circle(i,j,k:longint);
43   var ret,xa,ya,xb,yb,xc,yc,xd,yd,t1,t2:double;
44   begin
45     ret:=100/dis(i,j);
46     xa:=(p[i].x+p[j].x)/2; ya:=(p[i].y+p[j].y)/2;
47     xb:=xa-ret*(p[i].y-p[j].y); yb:=ya+ret*(p[i].x-p[j].x);
48     ret:=100/dis(j,k);
49     xc:=(p[j].x+p[k].x)/2; yc:=(p[j].y+p[k].y)/2;
50     xd:=xc-ret*(p[j].y-p[k].y); yd:=yc+ret*(p[j].x-p[k].x);
51     t1:=cross(xc-xa,yc-ya,xb-xa,yb-ya);
52     t2:=cross(xb-xa,yb-ya,xd-xa,yd-ya);
53     p[0].x:=(t1*xd+t2*xc)/(t1+t2);
54     p[0].y:=(t1*yd+t2*yc)/(t1+t2);
55     r:=dis(0,i);
56  end;
57
58 begin
59   readln(n);
60   for i:=1 to n do
61   begin
62     readln(p[i].x,p[i].y);
63     swap(p[i],p[trunc(random*i)+1]);
64   end;
65   little(1,2);
66   for i:=3 to n do
67     if not cov(i) then
68     begin
69       little(1,i);
70       for j:=2 to i-1 do
71         if not cov(j) then
72         begin
73           little(i,j);
74           for k:=1 to j-1 do
75             if not cov(k) then circle(i,j,k);
76         end;
77     end;
78   writeln(p[0].x:0:2,‘ ‘,p[0].y:0:2,‘ ‘,r:0:2);
79 end.

时间: 2024-10-13 09:46:25

bzoj2823的相关文章

bzoj2823【AHOI2012】信号塔

2823: [AHOI2012]信号塔 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 819  Solved: 372 [Submit][Status][Discuss] Description 在野外训练中,为了确保每位参加集训的成员安全,实时的掌握和收集周边环境和队员信息非常重要,集训队采用 的方式是在训练所在地散布N个小型传感器来收集并传递信息,这些传感器只与设在集训地中的信号塔进行通信, 信号塔接收信号的覆盖范围是圆形,可以接收到所有分

BZOJ2823: [AHOI2012]信号塔

2823: [AHOI2012]信号塔 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1097  Solved: 498[Submit][Status][Discuss] Description 在野外训练中,为了确保每位参加集训的成员安全,实时的掌握和收集周边环境和队员信息非常重要,集训队采用 的方式是在训练所在地散布N个小型传感器来收集并传递信息,这些传感器只与设在集训地中的信号塔进行通信, 信号塔接收信号的覆盖范围是圆形,可以接收到所有分布

【BZOJ2823】Sliding Window

经典单调队列 1 #include<cstdio> 2 #include<cstring> 3 using namespace std; 4 const int N=1000010; 5 int maxq[N],minq[N],a[N],ans1[N],ans2[N],lmax,lmin,rmax,rmin; 6 int main(){ 7 int n,k; 8 lmax=lmin=rmax=rmin=0; 9 scanf("%d %d",&n,&

【BZOJ2823】【AHOI2012】信号塔 最小圆覆盖 计算几何

链接: #include <stdio.h> int main() { puts("转载请注明出处[辗转山河弋流歌 by 空灰冰魂]谢谢"); puts("网址:blog.csdn.net/vmurder/article/details/46605193"); } 题解之前: 首先最小圆覆盖虽然有三层 for 循环,但是它是期望 O(n) 的.什么?你问我为啥?那我只能呵呵了,50W的 O(n3) 高速跑过. 后交的是不求凸包直接跑的,先交的是求了凸包再

[日常摸鱼]bzoj2823 [AHOI2012]信号塔

题意:$n$个点,求最小圆覆盖,$n \leq 5e5$ 这题数据是随机的hhh 我们可以先求出凸包然后对凸包上的点求最小圆覆盖-(不过直接求应该也行?) 反正随便写好像都能过- #include<cstdio> #include<algorithm> #include<cstdlib> #include<cmath> using namespace std; const int N=500005; struct Point { double x,y; in

bzoj2823: [AHOI2012]信号塔&amp;&amp;1336: [Balkan2002]Alien最小圆覆盖&amp;&amp;1337: 最小圆覆盖

首先我写了个凸包就溜了 这是最小圆覆盖问题,今晚学了一下 先随机化点,一个个加入 假设当前圆心为o,半径为r,加入的点为i 若i不在圆里面,令圆心为i,半径为0 再重新从1~i-1不停找j不在圆里面,令圆心为ij中点,直径为ij距离 再重新在1~j-1不停找k不在圆里面,三点可确定一圆,初中数学 复杂度看似O(n^3)实则O(n),好玄学 坑点:注意如果用点斜式表示方程有斜率为不存在的情况,需要特判 #include<cstdio> #include<iostream> #incl

BZOJ 刷题记录 PART 6

[BZOJ2709]水的二分加验证.可是好像被读入萎到了... [BZOJ3229]强大的算法见此.被机房的一堆大神"推荐".于是被坑了...写了一个下午... [BZOJ3631]这道题给我的启发是:要多想想算法. 開始一直在打树链剖分,打到一半忽然在众神犇的提(bi)示(shi)下.发现有O(N)的方法.试想:假设要支持区间改动(加减),最后再查询,能够用什么方法?固然,线段树和树状数组等等都能够,可是最好的显然是类似于前缀和的思想.比方在L~R加上一个数,能够再L处+K.在R+1

最小圆覆盖

本来不想学的-于是今天就碰到一道大裸题- 例题:bzoj2823 求最小圆覆盖n个点. 伪代码如下: 把所有点随机化,设为(x[1],y[1])...(x[n],y[n]) 开始把圆心设为x[1],半径设为0 for i=2 to n 如果i号点在当前圆内则跳过 //那么i号点就在圆周上 把1号点和i号点作为直径作一个圆 for j=1 to i-1 如果j号点在当前圆内则跳过 考虑以j号点和i号点作为直径作一个圆 for k=1 to j-1 如果k号点在当前圆内则跳过 以i,j,k三点组成的

[转载]hzwer的bzoj题单

counter: 664BZOJ1601 BZOJ1003 BZOJ1002 BZOJ1192 BZOJ1303 BZOJ1270 BZOJ3039 BZOJ1191 BZOJ1059 BZOJ1202 BZOJ1051 BZOJ1001 BZOJ1588 BZOJ1208 BZOJ1491 BZOJ1084 BZOJ1295 BZOJ3109 BZOJ1085 BZOJ1041 BZOJ1087 BZOJ3038 BZOJ1821 BZOJ1076 BZOJ2321 BZOJ1934 BZOJ