1 /*UVA 11168计算几何
2 凸包+数学思维
3 在直线同一侧的点,带入直线方程后,正负性是一致的,这个是解题的关键
4 所以运用点到直线的距离公式,可以O(1)计算出距离,枚举出最短距离即可
5 这里比较容易犯错的是:1、点斜式竖线无意义(也可用精度处理掉)2、点到直线的距离公式
6 */
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <math.h>
11 #include <ctype.h>
12 #include <string>
13 #include <iostream>
14 #include <sstream>
15 #include <vector>
16 #include <queue>
17 #include <stack>
18 #include <map>
19 #include <list>
20 #include <set>
21 #include <algorithm>
22 #define INF 0x3f3f3f3f
23 #define eps 1e-7
24 #define eps2 1e-3
25 #define zero(x) (((x)>0?(x):-(x))<eps)
26 using namespace std;
27
28
29 struct Point
30 {
31 double x,y;
32 Point() {}
33 Point(double xx,double yy)
34 {
35 x=xx;
36 y=yy;
37 }
38 bool operator<(const Point& p) const{
39 if (x==p.x) return y<p.y;
40 else return x<p.x;
41 }
42 }P1[10505],P2[10505];
43
44 typedef Point Vector;
45
46 bool operator==(Point A,Point B)
47 {
48 if ((fabs(A.x-B.x)<eps) && (fabs(A.y-B.y)<eps)) return true;
49 else return false;
50 }
51 Vector operator-(Point A,Point B)//表示A指向B
52 {
53 return Vector(A.x-B.x,A.y-B.y);
54 }
55 Vector operator*(Vector A,double k)
56 {
57 return Vector(A.x*k,A.y*k);
58 }
59 Vector operator+(Point A,Point B)//表示A指向B
60 {
61 return Vector(B.x+A.x,B.y+A.y);
62 }
63 double Cross(Vector A,Vector B)
64 {
65 return A.x*B.y-A.y*B.x;
66 }
67 double Area2(Point A,Point B,Point C)
68 {
69 return Cross(B-A,C-A);
70 }
71 //p是原先点的数组,n是个数,ch是凸包的点集
72 //精度要求高是用dcmp比较
73 //返回凸包点的个数
74 int ConvexHull(Point *p, int n, Point* ch){ //求凸包
75 sort(p, p + n);//先按照x,再按照y
76 int m = 0;
77 for(int i = 0; i < n; i++){
78 while(m > 1 && Cross(ch[m-1] - ch[m-2], p[i] - ch[m-2]) < 0) m--;
79 ch[m++] = p[i];
80 }
81 int k = m;
82 for(int i = n-2; i >= 0; i--){
83 while(m > k && Cross(ch[m-1] - ch[m-2], p[i] - ch[m-2]) < 0) m--;
84 ch[m++] = p[i];
85 }
86 if(n > 1) m--;
87 return m;
88 }
89 double ConvexPolygonArea(Point *p, int n){//凸包面积
90 double area = 0;
91 for(int i = 1; i < n-1; i++) area += Area2(p[0], p[i], p[i+1]);
92 return area / 2;
93 }
94
95 double X,Y;
96 int t,n,cnt;
97
98 double getdis(int k)
99 {
100
101 double ans=0;
102 Point p1=P2[k];
103 Point p2=P2[(k+1)%cnt];
104 if(fabs(p1.x-p2.x)<eps)//垂直线特判
105 {
106 for(int i=0;i<n;i++)//注意是所有点
107 {
108 double x=P1[i].x;
109 ans+=fabs(x-(p1.x+p2.x)/2);//取中点,减少精度损失
110 }
111
112 }else{//转化成y=kx+b方程
113 double xie=(p1.y-p2.y)/(p1.x-p2.x);
114 if(fabs(xie)<eps) xie=0;//调试中出现了负0
115 double b=p1.y-xie*p1.x;
116 double s=fabs(xie*X+b*n-Y),t=sqrt(xie*xie+1);
117 ans=s/(t+0.0);
118 }
119 return ans;
120 }
121 int main()
122 {
123
124 cin>>t;
125
126 for(int cas=1;cas<=t;cas++)
127 {
128 double ans=9999999999;
129 X=0,Y=0;
130 cin>>n;
131 for(int i=0;i<n;i++)
132 {
133 double x,y;cin>>x>>y;
134 P1[i]=Point(x,y);
135 X+=x,Y+=y;
136 }
137 cnt=ConvexHull(P1,n,P2);//凸包上的点
138 for(int i=0;i<cnt;i++)//枚举直线
139 ans=min(ans,getdis(i)/n);
140 printf("Case #%d: %.3lf\n",cas,ans);
141 }
142 return 0;
143 }