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 }

 

转载于:https://www.cnblogs.com/SilverNebula/p/6480885.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值