• UVa 11168(凸包、直线一般式)


    要点

    • 找凸包上的线很显然
    • 但每条线所有点都求一遍显然不可行,优化方法是:所有点都在一侧所以可以使用直线一般式的距离公式(frac{|A* sum{x}+B* sum{y}+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
    ", kase, Solve());
    	}
    }
    
  • 相关阅读:
    机器学习
    区块链
    MongoDB 生态 – 可视化管理工具
    分库分表适用场景
    权限管理
    ASP .NET Core 2.1 HTTP Error 502.5 – Process Failure
    Core2.0 项目到2.1
    Anaconda 安装和使用Numpy、Scipy、pandas、Scikit-learn
    NET Core 2.1.0 now available
    SQL Server发布订阅功能研究
  • 原文地址:https://www.cnblogs.com/AlphaWA/p/10961547.html
Copyright © 2020-2023  润新知