zoukankan      html  css  js  c++  java
  • P2742 [USACO5.1]圈奶牛Fencing the Cows /【模板】二维凸包

    计算几何……不会啊

    我们定义 (x)(y) 的叉积是 (|x||y| sin)
    用坐标表示就是 (x1y2-x2y1)
    根据叉积可以判断两个的夹角
    然后维护一个上凸壳和下凸壳,就可以求出凸包的周长了。

    // by Isaunoya
    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    struct io {
    	char buf[1 << 25 | 3], *s;
    	int f;
    	io() { f = 0, buf[fread(s = buf, 1, 1 << 25, stdin)] = '
    '; }
    	io& operator >> (int&x) {
    		for(x = f = 0; !isdigit(*s); ++s) f |= *s  == '-';
    		while(isdigit(*s)) x = x * 10 + (*s++ ^ 48);
    		return x = f ? -x : x, *this;
    	}
    };
    
    struct io_out {
    	char buf[1 << 25 | 3], *s = buf;
    	~io_out() { fwrite(buf, 1, s - buf, stdout); }
    	void write(int x) { if(x > 9) write(x / 10); *s++ = x % 10 ^ '0'; }
    	io_out& operator << (int x) {
    		if(x < 0) x = -x, *s++ = '-';
    		write(x); return *this;
    	}
    	io_out& operator << (char x) { *s++ = x; return *this; }
    } out;
    
    struct point { double x, y; } ;
    bool cmp(point a, point b) { return a.x < b.x; }
    
    int n;
    const int maxn = 1e5 + 51;
    point p[maxn];
    int st[maxn], v = 0;
    double ans = 0;
    
    double dis(int a, int b) { return sqrt((p[a].x - p[b].x) * (p[a].x - p[b].x) + (p[a].y - p[b].y) * (p[a].y - p[b].y)); }
    double ChaJi(point x, point y) { return x.x * y.y - x.y * y.x; }
    point operator - (point x, point y) {  return {x.x - y.x, x.y - y.y};}
    double cross(int x, int y, int z) { return ChaJi(p[y] - p[x], p[z] - p[x]); }
    void ins(int d) {
    	while(v >= 2 && cross(st[v - 1], st[v], d) <= 0) --v;
    	st[++ v] = d;
    }
    
    signed main() {
    #ifdef LOCAL
    	freopen("testdata.in", "r", stdin);
    #endif
    	ios :: sync_with_stdio(false);
    	cin.tie(nullptr), cout.tie(nullptr);
    	cin >> n ;
    	for(int i = 1 ; i <= n ; i ++)
    		cin >> p[i].x >> p[i].y;
    	sort(p + 1, p + n + 1, cmp);
    	st[++ v] = 1, st[++ v] = 2;
    	for(int i  = 3 ; i <= n ; i ++)
    		ins(i);
    	for(int i = 2 ; i <= v ; i ++)
    		ans += dis(st[i - 1], st[i]);
    	st[v = 1] = n, st[++ v] = n - 1;
    	for(int i = n - 2 ; i ; i --)
    		ins(i);
    	for(int i = 2 ; i <= v ; i ++)
    		ans += dis(st[i - 1], st[i]);
    	cout << fixed << setprecision(2) << ans << '
    ';
    	return 0;
    }
    
    
  • 相关阅读:
    在Windows Mobile 中如何改变Datagrid中字的颜色?
    使用FileSystemWatcher监视文件更改
    MVVM体验记之DataGrid绑定
    实现IDisposable以实现更优雅的代码
    适当使用enum做数据字典
    web.config customErrors无法处理的is not a valid virtual path
    Windows下使用skipfish
    MVVM打造无限级TreeView
    System.Drawing.Image在Save之后Type变了
    Windows下使用RatProxy
  • 原文地址:https://www.cnblogs.com/Isaunoya/p/12818978.html
Copyright © 2011-2022 走看看