UVa 11168(凸包直线一般式)

Posted alphawa

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UVa 11168(凸包直线一般式)相关的知识,希望对你有一定的参考价值。

要点

  • 找凸包上的线很显然
  • 但每条线所有点都求一遍显然不可行,优化方法是:所有点都在一侧所以可以使用直线一般式的距离公式\(\frac|A* \sumx+B* \sumy+C*n|\sqrt A^2+B^2\)\(O(1)\)算出总距离
#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

typedef double db;
const int maxn = 1e4 + 5;
const db eps = 1e-8;

int dcmp(db x) 
    if (fabs(x) < eps)  return 0;
    return x > 0 ? 1 : -1;


int T, n, cnt;
struct Point 
    db x, y;
    
    Point()

    Point(db a, db b):x(a), y(b)

    bool operator < (const Point &rhs) const 
        if (dcmp(x - rhs.x) != 0)   return dcmp(x - rhs.x) < 0;
        return dcmp(y - rhs.y) < 0;
    
p[maxn];
Point v[maxn];

db Cross(Point A, Point B) //顺时针转动则叉积为负
    return A.x * B.y - A.y * B.x;


Point operator - (Point A, Point B) 
    return Point(A.x - B.x, A.y - B.y);


bool operator == (Point A, Point B) 
    return dcmp(A.x - B.x) == 0 && dcmp(A.y - B.y) == 0;


void ConvexHull(int n) 
    cnt = 0;
    sort(p, p + n);
    n = unique(p, p + n) - p;//去重

    for (int i = 0; i < n; i++) 
        while (cnt > 1 && dcmp(Cross(v[cnt - 1] - v[cnt - 2], p[i] - v[cnt - 2])) <= 0) cnt--;
        v[cnt++] = p[i];
    
    int k = cnt;
    for (int i = n - 2; ~i; --i) 
        while (cnt > k && dcmp(Cross(v[cnt - 1] - v[cnt - 2], p[i] - v[cnt - 2])) <= 0) cnt--;
        v[cnt++] = p[i];
    
    if (n > 1)  cnt--;


db Solve() 
    if (n == 1) return 0;//特判
    db res = 1e18, X = 0, Y = 0;

    for (int i = 0; i < n; i++) 
        X += p[i].x;
        Y += p[i].y;
    
    for (int i = 0; i < cnt; i++) 
        Point a = v[i], b = v[(i + 1) % cnt];
        db A = b.y - a.y, B = a.x - b.x, C = Cross(b, a);
        db calc = fabs((A * X + B * Y + C * n) / sqrt(A * A + B * B));
        if (dcmp(calc - res) < 0) 
            res = calc;
        
    

    return res / n;


int main() 
    scanf("%d", &T);
    for (int kase = 1; kase <= T; kase++) 
        scanf("%d", &n);
        for (int i = 0; i < n; i++)
            scanf("%lf %lf", &p[i].x, &p[i].y);

        ConvexHull(n);//求凸包
        printf("Case #%d: %.3lf\n", kase, Solve());
    

以上是关于UVa 11168(凸包直线一般式)的主要内容,如果未能解决你的问题,请参考以下文章

UVA–11168 Airport[凸包]

UVA10256 The Great Divide(凸包相交)

UVA 10256 The Great Divide (判断凸包相交)

Airport UVA - 11168

UVA10256 The Great Divide

UVA378 Intersecting Lines