• 【POJ 1279】Art Gallery


    http://poj.org/problem?id=1279

    裸的半平面交的模板,按极角排序后维护一个双端队列,不要忘了最后要去除冗余,即最后一条边(或者更多的边)一定在双端队列里,但它不一定构成半平面,所以要特判。

    还有平行的边也要特判,因为平行的边的交点不可求!

    最后在poj上用G++交WA了好几次,换用C++就AC了/(ㄒoㄒ)/~~

    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const double Pi = acos(-1.0);
    const int N = 1503;
    int in() {
    	int k = 0, fh = 1; char c = getchar();
    	for(; c < '0' || c > '9'; c = getchar())
    		if (c == '-') fh = -1;
    	for(; c >= '0' && c <= '9'; c = getchar())
    		k = (k << 3) + (k << 1) + c - '0';
    	return k * fh;
    }
    
    struct Point {
    	double x, y;
    	Point(double _x = 0, double _y = 0) : x(_x), y(_y) {}
    } t[N], p[N];
    struct Line {
    	Point p, v;
    	double ang;
    	Line(Point _p = Point(0, 0), Point _v = Point(0, 0), double _ang = 0) : p(_p), v(_v), ang(_ang) {}
    	bool operator < (const Line &x) const {
    		return ang < x.ang;
    	}
    } l[N], q[N];
    
    Point operator + (Point a, Point b) {return Point(a.x + b.x, a.y + b.y);}
    Point operator - (Point a, Point b) {return Point(a.x - b.x, a.y - b.y);}
    Point operator * (Point a, double x) {return Point(a.x * x, a.y * x);}
    Point operator / (Point a, double x) {return Point(a.x / x, a.y / x);}
    
    double dcmp(double x) {return fabs(x) < 1e-8 ? 0 : (x < 0 ? -1 : 1);}
    double Dot(Point a, Point b) {return a.x * b.x + a.y * b.y;}
    double Cross(Point a, Point b) {return a.x * b.y - a.y * b.x;}
    double sqr(double x) {return x * x;}
    double dis(Point a, Point b) {return sqrt(sqr(a.x - b.x) + sqr(a.y - b.y));}
    bool onleft(Point a, Line b) {return dcmp(Cross(a - b.p, b.v)) < 0;}
    Point intersection(Line a, Line b) {
    	Point u; double t;
    	u = a.p - b.p;
    	t = Cross(b.v, u) / Cross(a.v, b.v);
    	return a.p + a.v * t;
    }
    
    int n;
    
    double mkhalf() {
    	q[1] = l[1]; q[2] = l[2];
    	p[1] = intersection(q[1], q[2]);
    	
    	int head = 1, tail = 2;
    	for(int i = 3; i <= n; ++i) {
    		while (head < tail && !onleft(p[tail - 1], l[i])) --tail;
    		while (head < tail && !onleft(p[head], l[i])) ++head;
    		q[++tail] = l[i];
    		if (dcmp(Cross(q[tail].v, q[tail - 1].v)) == 0) {
    			--tail;
    			if (onleft(l[i].p, q[tail])) q[tail] = l[i];
    		}
    		if (head < tail) p[tail - 1] = intersection(q[tail - 1], q[tail]);
    	}
    	while (head < tail && !onleft(p[tail - 1], q[head])) --tail;
    	p[tail] = intersection(q[head], q[tail]);
    	
    	if (tail - head <= 1) return 0;
    	else {
    		double ret = 0;
    		p[tail + 1] = p[head];
    		for(int i = head; i <= tail; ++i)
    			ret += Cross(p[i], p[i + 1]);
    		return ret / 2;
    	}
    }
    
    int main() {
    	int T = in();
    	while (T--) {
    		n = in();
    		for(int i = 1; i <= n; ++i) scanf("%lf%lf", &t[i].x, &t[i].y);
    		t[n + 1] = t[1];
    		for(int i = 1; i <= n; ++i)
    			l[i] = Line(t[i + 1], t[i] - t[i + 1], atan2(t[i].y - t[i + 1].y, t[i].x - t[i + 1].x));
    		
    		sort(l + 1, l + n + 1);
    		
    		printf("%.2lf
    ", mkhalf());	
    	}
    	
    	return 0;
    }
    

    _(:з」∠)_

  • 相关阅读:
    next()nextLine()以及nextInt()的区别及用法【转载】
    JAVA集合 list set map
    JAVA求回文数
    左移右移操作_进制转换与区分
    window_mysql踩坑
    centos_mysql踩坑
    【纪中受难记】——C3D6:大小不分
    zzLinux 中直接 I/O 机制的介绍https://www.ibm.com/developerworks/cn/linux/l-cn-directio/
    zz-zookeeper 启动失败 BindException: Address already in use 或者Error contacting service. It is probably not running
    zz---对象存储(Object-based Storage)概述
  • 原文地址:https://www.cnblogs.com/abclzr/p/5676835.html
Copyright © 2020-2023  润新知