• [洛谷P2742]【模板】二维凸包([USACO5.1]圈奶牛Fencing the Cows)


    题目大意:求一个点集凸包边长

    题解:求凸包,直接求

    卡点:发现在较后面数位上有较小的误差,还以为是浮点数误差,最后发现是构造函数写成了$int$类型

    C++ Code:

    #include <algorithm>
    #include <cstdio>
    #include <cmath>
    #include <iostream>
    #include <iomanip>
    #define maxn 10010
    
    inline double sqr(double x) { return x * x; }
    struct Point {
    	double x, y;
    	Point() { }
    	Point(double __x, double __y) : x(__x), y(__y) { }
    	inline Point operator - (const Point &rhs) const {
    		return Point(x - rhs.x, y - rhs.y);
    	}
    	inline Point operator + (const Point &rhs) const {
    		return Point(x + rhs.x, y + rhs.y);
    	}
    	inline double operator * (const Point &rhs) const {
    		return x * rhs.y - y * rhs.x;
    	}
    } O, s[maxn], v[maxn];
    inline double abs2(const Point &x) { return sqr(x.x) + sqr(x.y); }
    inline double dis(const Point &lhs, const Point &rhs) { return sqrt(abs2(rhs - lhs)); }
    inline double det(const Point &O, const Point &lhs, const Point &rhs) {
    	return (lhs - O) * (rhs - O);
    }
    inline bool operator < (const Point &lhs, const Point &rhs) {
    	static Point X, Y; X = lhs - O, Y = rhs - O;
    	static double t; t = X * Y;
    	return (t > 0) || (t == 0 && abs2(X) > abs2(Y));
    }
    
    int n, tot;
    int main() {
    	std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0);
    	std::cin >> n;
    	if (n <= 1) {
    		std::cout << "0
    ";
    		return 0;
    	}
    	int miny = 0;
    	for (int i = 0; i < n; ++i) {
    		std::cin >> s[i].x >> s[i].y;
    		if ((s[i].y < s[miny].y) || (s[i].y == s[miny].y && s[i].x < s[miny].x)) miny = i;
    	}
    	if (n == 2) {
    		std::cout << std::fixed << std::setprecision(2) << dis(s[0], s[1]) * 2 << '
    ';
    		return 0;
    	}
    	O = s[miny]; std::swap(s[0], s[miny]);
    	std::sort(s + 1, s + n);
    	v[0] = s[0], v[1] = s[1], v[2] = s[2], tot = 3;
    	for (int i = 3; i < n; ++i) {
    		for (Point a = v[tot - 2], b = v[tot - 1]; tot > 2 && det(a, b, s[i]) <= 0; a = v[tot - 2], b = v[tot - 1]) --tot;
    		v[tot++] = s[i];
    	}
    	double ans = 0;
    	for (int i = 0, nxt = 0; i < tot; ++i) {
    		nxt += 1 - tot;
    		nxt += nxt >> 31 & tot;
    		ans += dis(v[i], v[nxt]);
    	}
    	std::cout << std::fixed << std::setprecision(2) << ans << '
    ';
    	return 0;
    }
    

      

  • 相关阅读:
    AlterDialog 经常使用的样式
    C++编程-&gt;pair(对组)
    arcgis server10.2.2公布地图基础服务的详细步骤
    solr实战-(一)
    iOS开发-自己定义重用机制给ScrollerView加入子视图
    Day2下午解题报告
    Day2二分图笔记
    考前冲刺班成绩
    Day2平衡树笔记
    Day2上午解题报告
  • 原文地址:https://www.cnblogs.com/Memory-of-winter/p/10348966.html
Copyright © 2020-2023  润新知