zoukankan      html  css  js  c++  java
  • 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
    ");
    73             continue;
    74         }
    75         printf("%.3lf
    ", Line( ConvexHull() ) / (N*1.0));
    76     }
    77     return 0;
    78 }
    View Code
  • 相关阅读:
    POJ 2236 Wireless Network(并查集)
    POJ 2010 Moo University
    POJ 3614 Sunscreen(贪心,区间单点匹配)
    POJ 2184 Cow Exhibition(背包)
    POJ 1631 Bridging signals(LIS的等价表述)
    POJ 3181 Dollar Dayz(递推,两个long long)
    POJ 3046 Ant Counting(递推,和号优化)
    POJ 3280 Cheapest Palindrome(区间dp)
    POJ 3616 Milking Time(dp)
    POJ 2385 Apple Catching(01背包)
  • 原文地址:https://www.cnblogs.com/qiu520/p/3666261.html
Copyright © 2011-2022 走看看