標籤:space 輸出 dia 覆蓋 unit iam recommend end ted
| 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 minimal required length of the rope . As follow,
To make this problem more simple, consider all the trees are circles in a plate. The diameter of all the trees are the same (the diameter of a tree is 1 unit). Kiki can calculate the minimal length of the rope , because it‘s so easy for this smart girl.
But we don‘t have a rope to surround the trees. Instead, we only have some circle rings of different radius. Now I want to know the minimal required radius of the circle ring. And I don‘t want to ask her this problem, because she is busy preparing for the examination.
As a smart ACMer, can you help me ?
|
InputThe input contains one or more data sets. At first line of each input data set is number of trees in this data set n (1 <= n <= 100), it is followed by n coordinates of the trees. Each coordinate is a pair of integers, and each integer is in [-1000, 1000], it means the position of a tree’s center. Each pair is separated by blank.
Zero at line for number of trees terminates the input for your program. |
| OutputMinimal required radius of the circle ring I have to choose. The precision should be 10^-2. |
Sample Input
21 0-1 00 |
Sample Output
1.50 |
| Authorzjt |
| |
| Recommendlcy |
/*題意:給你散落的點,讓你求出最小的圓,將這些點圍起來,點可以在圓上,輸出圓的最小半徑。初步思路:求出凸包,然後在求出這個凸包的外接圓,兩條邊的垂直平分線的交點就是圓心#錯誤:有點天真,三角形一定有外接圓,但是多邊形不一定有外接圓#改進:求出凸包,然後求凸包的最小覆蓋圓,這個名詞也是看到部落格才知道了(嗚嗚嗚,又少了 一次好好動腦的機會)然後任意的三個點組成的三角形的外接圓的最大半徑就是就是凸包 “外接圓”的半徑了,三角形的外接圓半徑為abc/4s,這個公式能簡單的證明。遍曆出所有的半徑,中間最長的半徑 就是要求的半徑。#改進錯誤點:上面的情況只適用於銳角三角形,鈍角,直角三角形的“外接圓”的最小半徑,不是外接圓的半徑,而是最長邊的一半! */#include<bits/stdc++.h>using namespace std;/****************************凸包模板*******************************/const double eps = 1e-8;int sgn(double x){ if(fabs(x) < eps)return 0; if(x < 0)return -1; else return 1;}struct Point{ double x,y; Point(){} Point(double _x,double _y) { x = _x;y = _y; } Point operator -(const Point &b)const { return Point(x - b.x,y - b.y); } //叉積 double operator ^(const Point &b)const { return x*b.y - y*b.x; } //點積 double operator *(const Point &b)const { return x*b.x + y*b.y; } void input(){ scanf("%lf%lf",&x,&y); }};struct Line { Point s,e; Line(){} Line(Point _s,Point _e) { s = _s; e = _e; }}; //*兩點間距離double dist(Point a,Point b){ return sqrt((a-b)*(a-b));} /** 求凸包,Graham演算法* 點的編號0~n-1* 返回凸包結果Stack[0~top-1]為凸包的編號*/const int MAXN = 105;Point List[MAXN];int Stack[MAXN];//用來存放凸包的點int top;//表示凸包中點的個數//相對於List[0]的極角排序bool _cmp(Point p1,Point p2){ double tmp = (p1-List[0])^(p2-List[0]); if(sgn(tmp) > 0) return true; else if(sgn(tmp) == 0 && sgn(dist(p1,List[0]) - dist(p2,List[0])) <= 0) return true; else return false;}void Graham(int n){ Point p0; int k = 0; p0 = List[0]; //找最下邊的一個點 for(int i = 1;i < n;i++) { if( (p0.y > List[i].y) || (p0.y == List[i].y && p0.x > List[i].x) ) { p0 = List[i]; k = i; } } swap(List[k],List[0]); sort(List+1,List+n,_cmp); if(n == 1) { top = 1; Stack[0] = 0; return; } if(n == 2) { top = 2; Stack[0] = 0; Stack[1] = 1; return ; } Stack[0] = 0; Stack[1] = 1; top = 2; for(int i = 2;i < n;i++) { while(top > 1 && sgn((List[Stack[top-1]]-List[Stack[top-2]])^(List[i]-List[Stack[top-2]])) <= 0) top--; Stack[top++] = i; }}/****************************凸包模板*******************************/int n;int main(){ // freopen("in.txt","r",stdin); while(scanf("%d",&n)!=EOF&&n){ for(int i=0;i<n;i++){ List[i].input(); }//輸入所有點座標 if(n==1){ printf("0.50\n"); continue; } if(n==2){ printf("%.2lf\n",dist(List[0],List[1])/2+0.5); continue; } Graham(n);//求出凸包 double Maxr=-1.0; // cout<<top<<endl; //將Static[0]作為所有小三角形的公用頂點 for(int i=0;i<top;i++){//枚舉三角形的點 for(int j=i+1;j<top;j++){ for(int k=j+1;k<top;k++){ /* 三條邊的長度 */ double a=dist(List[Stack[i]],List[Stack[j]]); double b=dist(List[Stack[i]],List[Stack[k]]); double c=dist(List[Stack[k]],List[Stack[j]]); if(a*a+b*b<c*c||a*a+c*c<b*b||b*b+c*c<a*a){//判斷是不是銳角三角形 Maxr=max(Maxr,max(max(a,b),c)/2); }else{ /* 三角形的面積 */ Point x1=List[Stack[j]]-List[Stack[i]]; Point x2=List[Stack[k]]-List[Stack[i]]; double s=fabs(x1^x2)/2; Maxr=max(Maxr,(a*b*c)/(4*s)); } } } } printf("%.2lf\n",Maxr+0.5); } return 0;}
Maple trees(最小覆蓋圓)