• 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
  • 相关阅读:
    Android无线测试之—UiAutomator UiSelector API介绍之四
    Android无线测试之—UiAutomator UiSelector API介绍之三
    Android无线测试之—UiAutomator UiSelector API介绍之二
    网页抓取- 3
    VC 6.0 LNK2005 错误 处理
    抓取网页(3)之部分工程文件
    网页抓取 (2)
    网页抓取总结(一)
    nyoj-291 互素数个数 欧拉函数
    nyoj-257 郁闷的C小加(一) 前缀表达式变后缀
  • 原文地址:https://www.cnblogs.com/qiu520/p/3666261.html
Copyright © 2020-2023  润新知