ZOJ1450 Minimal Circle

You are to write a program to find a circle which covers a set of points and has the minimal area. There will be no more than 100 points in one problem.

 

Input

 

The input contains several problems. The first line of each problem is a line containing only one integer N which indicates the number of points to be covered. The next N lines contain N points. Each point is represented by x and y coordinates separated by a space. After the last problem, there will be a line contains only a zero.

 

Output

 

For each input problem, you should give a one-line answer which contains three numbers separated by spaces. The first two numbers indicate the x and y coordinates of the result circle, and the third number is the radius of the circle. (use escape sequence %.2f)

 

Sample Input

 

2
0.0 0.0
3 0
5
0 0
0 1
1 0
1 1
2 2
0

 

Sample Output

 

1.50 0.00 1.50
1.00 1.00 1.41

 

数学问题 几何

最小圆覆盖,随机增量法

其实就是枚举两个点作为圆直径上的两点,发现有点在当前圆外时,就调整直径……

 

随机增量法求最小圆覆盖。

三重循环。

令ci为前i个点的覆盖圆,新加入一个点i+1时,若其在圆内,跳过,若其在圆外,修改圆心使i+1在圆c(i+1)上。

检查之前的点,令ci为前i个点的覆盖圆,且点j在圆周上,若第i+1个点无法被圆覆盖,修改圆心使点i+1和点j都在圆周上。

检查之前的点,令ci为前i个点的覆盖圆,且点j和点k在圆周上,若第i+1个点无法被圆覆盖,修改圆心使点i+1和点j、点k都在圆周上

这算法倒是还能理解,但是求外心的几何算法表示看不懂。这个技能还是等高二再解锁吧。

      ——高一时候的博主

 

↑什么解锁技能啊……现在一回顾,就是设外心坐标,根据外心到三个顶点的距离相等来暴力列方程,解出来个表达式就行……

 

 1 /*by SilverN*/
 2 #include<algorithm>
 3 #include<iostream>
 4 #include<cstring>
 5 #include<cstdio>
 6 #include<cmath>
 7 using namespace std;
 8 const double eps=1e-9;
 9 const int mxn=100010;
10 struct Point{
11     double x,y;
12     Point operator + (Point rhs){return (Point){x+rhs.x,y+rhs.y};}
13     Point operator - (Point rhs){return (Point){x-rhs.x,y-rhs.y};}
14     double cross(Point rhs){return x*rhs.y-y*rhs.x;}
15     friend double dist(Point a,Point b){
16         return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
17     }
18 }p[mxn],O;
19 int n;
20 double r;
21 void clc(Point p1,Point p2,Point p3){//计算三角形外心 
22     double a=2*(p2.x-p1.x);
23     double b=2*(p2.y-p1.y);
24     double c=p2.x*p2.x+p2.y*p2.y-p1.x*p1.x-p1.y*p1.y;
25     double d=2*(p3.x-p1.x);
26     double e=2*(p3.y-p1.y);
27     double f=p3.x*p3.x+p3.y*p3.y-p1.x*p1.x-p1.y*p1.y;
28     O.y=(d*c-a*f)/(b*d-e*a);
29     O.x=(b*f-e*c)/(b*d-e*a);
30     r=dist(O,p1);
31     return;
32 }
33 int main(){
34     int i,j;
35     while(scanf("%d",&n) && n){
36         for(i=1;i<=n;i++){scanf("%lf%lf",&p[i].x,&p[i].y);}
37         O=p[1];r=0;
38         for(int i=2;i<=n;i++)
39             if(dist(O,p[i])>r+eps){
40                 O=p[i];r=0;
41                 for(j=1;j<i;j++){
42                     if(dist(O,p[j])>r+eps){
43                         O.x=(p[i].x+p[j].x)/2;
44                         O.y=(p[i].y+p[j].y)/2;
45                         r=dist(O,p[j]);
46                         for(int k=1;k<j;k++){
47                             if(dist(O,p[k])>r+eps)
48                                 clc(p[i],p[j],p[k]);
49                         }
50                     }
51                 }
52             }
53         printf("%.2f %.2f %.2f\n",O.x,O.y,r);
54     }
55     return 0;
56 }

 

posted @ 2017-02-28 20:54  SilverNebula  阅读(156)  评论(0编辑  收藏  举报
AmazingCounters.com