zoukankan      html  css  js  c++  java
  • [SHOI2012]信用卡凸包(计算几何)

    /*
    考验观察法?? 
    
    可以发现最终答案等于所有作为圆心的点求出凸包的周长加上一个圆的周长 
    向量旋转
    
    (x1, y1) 相较于 (x2, y2) 旋转角c 答案是
    
    (dtx * cosc - dty * sinc + x2, dty * cosc + dtx * sinc + y2) 
    
    貌似我的凸包也不鲁棒耶 
    
    */
    
    
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<iostream>
    #include<cmath> 
    #include<queue>
    #define ll long long 
    #define M 400010
    #define mmp make_pair
    using namespace std;
    int read()
    {
    	int nm = 0, f = 1;
    	char c = getchar();
    	for(; !isdigit(c); c = getchar()) if(c == '-') f = -1;
    	for(; isdigit(c); c = getchar()) nm = nm * 10 + c - '0';
    	return nm * f;
    }
    const double pi = acos(-1), eps = 1e-12;
    struct Vec
    {
    	double x, y;
    }pt[M];
    double operator * (const Vec &a, const Vec &b)
    {
    	return a.x * b.y - a.y * b.x;
    }
    
    Vec operator + (Vec a, Vec b)
    {
    	return Vec{a.x + b.x, a.y + b.y};
    }
    
    Vec operator - (Vec a, Vec b)
    {
    	return Vec{a.x - b.x, a.y - b.y};
    }
    
    double cross(Vec a, Vec b, Vec c)
    {
    	return (a - c) * (b - c); 
    }
    
    bool cmp1(Vec a, Vec b)
    {
    	return a.y == b.y ? a.x < b.x : a.y < b.y;
    }
    
    bool cmp(Vec a, Vec b)
    {
    	return cross(a, b, pt[1]) >= 0;
    }
    
    Vec rotate(Vec a, double p)
    {
    	return Vec{a.x * cos(p) - a.y * sin(p), a.y * cos(p) + a.x * sin(p)};
    }
    
    double diss(Vec a, Vec b)
    {
    	double x = a.x - b.x, y = a.y - b.y;
    	return sqrt(x * x + y * y);
    }
    
    double r, h, l, a, b, ap;
    int n, tp, sta[M]; 
    
    
    
    
    
    int main()
    {
    	n = read();
    	scanf("%lf%lf%lf", &l, &h, &r);
    	h = (h - r * 2) / 2.0, l = (l - r * 2) / 2.0;
    	for(int i = 1; i <= n; i++)
    	{
    		scanf("%lf%lf%lf", &a, &b, &ap);
    		pt[i] = rotate(Vec{h, l}, ap) + Vec{a, b};
    		pt[i + 2 * n] = rotate(Vec{-h, l}, ap) + Vec{a, b};
    		pt[i + 3 * n] = rotate(Vec{h, -l}, ap) + Vec{a, b};
    		pt[i + n] = rotate(Vec{-h, -l}, ap) + Vec{a, b};
    	}
    	n *= 4;
    	sort(pt + 1, pt + n + 1, cmp1);
    	sta[++tp] = 1;
    	sort(pt + 2, pt + n + 1, cmp);
    	sta[++tp] = 2;
    	sta[++tp] = 3;
    	for(int i = 4; i <= n; i++)
    	{
    		while(tp > 1 && cross(pt[i], pt[sta[tp]], pt[sta[tp - 1]]) >= 0) tp--;
    		sta[++tp] = i;
    	}
    	double ans = 0;
    	for(int i = 1; i < tp; i++) ans += diss(pt[sta[i]], pt[sta[i + 1]]);
    	ans += diss(pt[sta[1]], pt[sta[tp]]);
    	ans += r * pi * 2; 
    	printf("%.2lf
    ", ans);
    	return 0;
    }
    
  • 相关阅读:
    SPOJ VJudge QTREE
    LCA 在线倍增法 求最近公共祖先
    Codevs 2370 小机房的树
    51Nod-1632-B君的连通
    51Nod--1100-斜率最大
    51Nod-1276-岛屿的数量
    51Nod-1270-数组的最大代价
    poj
    hihocoder Week136 -- 优化延迟
    poj-1035-Spell Checker
  • 原文地址:https://www.cnblogs.com/luoyibujue/p/10679581.html
Copyright © 2011-2022 走看看