zoj 1450 Minimal Circle 最小覆盖圆

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=450

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.

题意描述:找到一个最小圆能够包含到所有的二维坐标点。

算法分析:最小覆盖圆的做法。

  1 //最小覆盖圆
  2 #include<iostream>
  3 #include<cstdio>
  4 #include<cstring>
  5 #include<cstdlib>
  6 #include<cmath>
  7 #include<algorithm>
  8 #define inf 0x7fffffff
  9 #define exp 1e-10
 10 #define PI 3.141592654
 11 using namespace std;
 12 const int maxn=1000+10;
 13 struct Point
 14 {
 15     double x,y;
 16     Point(double x=0,double y=0):x(x),y(y){}
 17 }an[maxn],d;//d:最小覆盖圆的圆心坐标
 18 double r;//最小覆盖圆的半径
 19 typedef Point Vector;
 20 Vector operator + (Vector A,Vector B) {return Vector(A.x+B.x , A.y+B.y); }
 21 Vector operator - (Vector A,Vector B) {return Vector(A.x-B.x , A.y-B.y); }
 22 Vector operator * (Vector A,double p) {return Vector(A.x*p , A.y*p); }
 23 Vector operator / (Vector A,double p) {return Vector(A.x/p , A.y/p); }
 24 int dcmp(double x)
 25 {
 26     if (fabs(x)<exp) return 0;
 27     return x<0 ? -1 : 1;
 28 }
 29 double cross(Vector A,Vector B)
 30 {
 31     return A.x*B.y-B.x*A.y;
 32 }
 33 double dist(Vector A,Vector B)
 34 {
 35     double x=(A.x-B.x)*(A.x-B.x);
 36     double y=(A.y-B.y)*(A.y-B.y);
 37     return sqrt(x+y);
 38 }
 39
 40 void MiniDiscWith2Point(Point p,Point q,int n)
 41 {
 42     d=(p+q)/2.0;
 43     r=dist(p,q)/2;
 44     int k;
 45     double c1,c2,t1,t2,t3;
 46     for (k=1 ;k<=n ;k++)
 47     {
 48         if (dist(d,an[k])<=r) continue;
 49         if (dcmp(cross(p-an[k],q-an[k]))!=0)
 50         {
 51             c1=(p.x*p.x+p.y*p.y-q.x*q.x-q.y*q.y)/2.0;
 52             c2=(p.x*p.x+p.y*p.y-an[k].x*an[k].x-an[k].y*an[k].y)/2.0;
 53             d.x=(c1*(p.y-an[k].y)-c2*(p.y-q.y))/((p.x-q.x)*(p.y-an[k].y)-(p.x-an[k].x)*(p.y-q.y));
 54             d.y=(c1*(p.x-an[k].x)-c2*(p.x-q.x))/((p.y-q.y)*(p.x-an[k].x)-(p.y-an[k].y)*(p.x-q.x));
 55             r=dist(d,an[k]);
 56         }
 57         else
 58         {
 59             t1=dist(p,q);
 60             t2=dist(q,an[k]);
 61             t3=dist(p,an[k]);
 62             if (t1>=t2 && t1>=t3)
 63             {
 64                 d=(p+q)/2.0;
 65                 r=dist(p,q)/2.0;
 66             }
 67             else if (t2>=t1 && t2>=t3)
 68             {
 69                 d=(an[k]+q)/2.0;
 70                 r=dist(an[k],q)/2.0;
 71             }
 72             else
 73             {
 74                 d=(an[k]+p)/2.0;
 75                 r=dist(an[k],p)/2.0;
 76             }
 77         }
 78     }
 79 }
 80 void MiniDiscWithPoint(Point p,int n)
 81 {
 82     d=(p+an[1])/2.0;
 83     r=dist(p,an[1])/2.0;
 84     int j;
 85     for (j=2 ;j<=n ;j++)
 86     {
 87         if (dist(d,an[j])<=r) continue;
 88         else
 89         {
 90             MiniDiscWith2Point(p,an[j],j-1);
 91         }
 92     }
 93 }
 94
 95 int main()
 96 {
 97     int n;
 98     while (scanf("%d",&n)!=EOF && n)
 99     {
100         for (int i=1 ;i<=n ;i++)
101         {
102             scanf("%lf%lf",&an[i].x,&an[i].y);
103         }
104         if (n==1)
105         {
106             printf("%lf %lf\n",an[1].x,an[1].y);
107             continue;
108         }
109         r=dist(an[1],an[2])/2.0;
110         d=(an[1]+an[2])/2.0;
111         for (int i=3 ;i<=n ;i++)
112         {
113             if (dist(d,an[i])<=r) continue;
114             else
115             MiniDiscWithPoint(an[i],i-1);
116         }
117         printf("%.2lf %.2lf %.2lf\n",d.x,d.y,r);
118     }
119     return 0;
120 }
时间: 2024-11-09 00:56:48

zoj 1450 Minimal Circle 最小覆盖圆的相关文章

ZOJ 1450 Minimal Circle 最小圆覆盖

套了个模板直接上,貌似没有随机化序列 QAQ //#pragma comment(linker, "/STACK:16777216") //for c++ Compiler #include <stdio.h> #include <iostream> #include <cstring> #include <cmath> #include <stack> #include <queue> #include <

Maple trees(最小覆盖圆)

Maple trees Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 222 Accepted Submission(s): 79   Problem Description There are a lot of trees in HDU. Kiki want to surround all the trees with the minim

hdu2215(最小覆盖圆)

Maple trees Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1578    Accepted Submission(s): 488 Problem Description There are a lot of trees in HDU. Kiki want to surround all the trees with the

(hdu step 7.1.5)Maple trees(求凸包的最小覆盖圆的半径)

题目: Maple trees Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 177 Accepted Submission(s): 63   Problem Description There are a lot of trees in HDU. Kiki want to surround all the trees with the m

ZOJ 1450

最小圆覆盖 #include <iostream> #include <algorithm> #include <cstdio> #include <cmath> using namespace std; const double eps=0.00000001; struct point { double x,y; }p[110]; struct circle{ point cent; double rad; }cir; int n; double Tria

最小覆盖圆算法

最小圆覆盖,很经典的问题.题目大概是,平面上n个点,求一个半径最小的圆,能够覆盖所有的点. 算法有点难懂,于是讲讲我的理解. 如果要求一个最小覆盖圆,这个圆至少要由三个点确定.有一种算法就是任意取三个点作圆,然后判断距离圆心最远的点是否在圆内,若在,则完成:若不在则用最远点更新这个圆. 这里介绍的算法是,先任意选取两个点,以这两个点的连线为直径作圆.再以此判断剩余的点,看它们是否都在圆内(或圆上),如果都在,说明这个圆已经找到.如果没有都在:假设我们用的最开始的两个点为p[1],p[2],并且找

最小覆盖圆

给出一堆点,求一个面积(半径)最小的圆,使得所有点都在它的内部或边界上. 随机增量法是这样的.... 先随机打乱点的顺序...... 然后,我们假设已经得到了点 $1,2,...,i$ 的最小覆盖圆,我们要求出点 $1,2,...,i,i+1$ 的最小覆盖圆. 怎么做? 考虑点 $i+1$ ,分两种情况: 1.如果点 $i+1$ 在点 $1,2,...,i$ 的最小覆盖圆里面或边界上,那么点 $1,2,...,i,i+1$ 的最小覆盖圆就是点 $1,2,...,i$ 的最小覆盖圆. 证明: 假设

[matlab] 10.最小覆盖圆

clear all; close all; clc; n=100; p=rand(n,2); p1=p(1,:); %取第一行的值 P1点 p2=p(2,:); %取第二行的值 P2点 r=sqrt((p1(1)-p2(1))^2+(p1(2)-p2(2))^2)/2; %求两点半径 cenp=(p1+p2)/2; %求两点中点 for i=3:n newp=p(i,:); %从第三行开始 储存新的点 d=sqrt((cenp(1)-newp(1))^2+(cenp(2)-newp(2))^2)

POJ 2546 &amp; ZOJ 1597 Circular Area 两圆的面积交

Circular Area Time Limit: 2 Seconds      Memory Limit: 65536 KB Your task is to write a program, which, given two circles, calculates the area of their intersection with the accuracy of three digits after decimal point. Input In the single line of in