UVa 11168 Airport凸包与直线方程

题意:给出平面上的n个点,求一条直线,使得所有点在该直线的同一侧且所有点到该直线的距离和最小,输出该距离和。

思路:要使所有点在该直线的同一侧,明显是直接利用凸包的边更优。所以枚举凸包的没条边,然后求距离和。直线一般式为Ax + By + C = 0.点(x0, y0)到直线的距离为

fabs(Ax0+By0+C)/sqrt(A*A+B*B).由于所有点在直线的同一侧,那么对于所有点,他们的(Ax0+By0+C)符号相同,显然可以累加出sumX和sumY,然后统一求和。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cmath>
 4 #include<iostream>
 5 #include<algorithm>
 6 using namespace std;
 7 #define INF 800000000
 8 int sumX, sumY, N;
 9 struct Point{int x, y;};
10 Point p[10002], ch[10002];
11 bool cmp(Point a, Point b){
12     return a.x == b.x ? a.y < b.y : a.x < b.x;
13 }
14 int Cross(Point a, Point b, Point c){
15     return (a.x-c.x)*(b.y-c.y) - (a.y-c.y)*(b.x-c.x);
16 }
17 const double eps = 1e-10;
18 int Dcmp(double x){
19     if(x < eps)return 0;
20     return x < 0 ? -1 : 1;
21 }
22 int ConvexHull()//凸包
23 {
24     sort(p, p+N, cmp);
25     int m = 0;
26     for(int i = 0; i < N; i++){
27         while(m > 1 && Dcmp(Cross(ch[m-1], p[i], ch[m-2])) <= 0)m--;
28         ch[m++] = p[i];
29     }
30     int k = m;
31     for(int i = N-2; i >= 0; i--){
32         while(m > k && Dcmp(Cross(ch[m-1], p[i], ch[m-2])) <= 0)m--;
33         ch[m++] = p[i];
34     }
35     if(N > 1)m--;
36     return m;
37 }
38 double getDist(Point a, Point b){
39     double A, B, C, k, v;
40     A = a.y - b.y;
41     B = b.x - a.x;
42     C = a.x*b.y - a.y*b.x;
43     k = fabs(A*sumX + B*sumY + N * C);
44     v = sqrt(A * A + B * B);
45     return k / v;
46 }
47 double Line(int m)
48 {
49     double minL = INF*1.0, L;
50     for(int i = 0; i < m; i++){
51         L = getDist(ch[i], ch[(i+1)%m]);//得到所有点到凸包一条边的距离
52         minL = min(minL, L);
53     }
54     return minL;
55 }
56 int main()
57 {
58     int i, j, t;
59     cin>>t;
60     int cas = 1;
61     while(t--)
62     {
63         cin>>N;
64         sumX = sumY = 0;
65         for(i = 0; i < N; i++){
66             scanf("%d%d", &p[i].x, &p[i].y);
67             sumX += p[i].x;
68             sumY += p[i].y;
69         }
70         printf("Case #%d: ", cas++);
71         if(N == 1 || N== 2){
72             printf("0.000\n");
73             continue;
74         }
75         printf("%.3lf\n", Line( ConvexHull() ) / (N*1.0));
76     }
77     return 0;
78 }
View Code

 

posted @ 2014-04-15 14:57  SStep  阅读(135)  评论(0编辑  收藏  举报