zoukankan      html  css  js  c++  java
  • [CQOI2006]凸多边形

    一年前写的代码现在已经惨不忍睹了,趁着 olinr讲计算几何,再打一遍板子。

    半平面交的步骤是:

    1. 将所有半平面极角排序

    2. 维护一个双端队列,按照极角序更新首尾的半平面,然后插入半平面

    3. 最后再将首尾更新一次

    最后队列里所有的半平面即为答案。

    下面是重写后的代码,感觉好看多了~

    #include <bits/stdc++.h>
    using namespace std;
    
    const double eps  = 1e-6;
    
    struct Vector
    {
    	double x, y;
    	Vector(double x = 0, double y = 0) : x(x), y(y) {}
    	double mod() {return sqrt(x * x + y * y);}
    };
    
    struct Line
    {
    	Vector p, v;
    }a[510];
    
    int n, nn;
    
    Vector operator+(const Vector &a, const Vector &b) {return Vector(a.x + b.x, a.y + b.y);}
    Vector operator-(const Vector &a, const Vector &b) {return Vector(a.x - b.x, a.y - b.y);}
    Vector operator*(const Vector &a, const double &b) {return Vector(a.x * b, a.y * b);}
    Vector operator/(const Vector &a, const double &b) {return Vector(a.x / b, a.y / b);}
    Vector operator*(const double &a, const Vector &b) {return Vector(a * b.x, a * b.y);}
    double operator*(const Vector &a, const Vector &b) {return a.x * b.x + a.y * b.y;}
    double operator^(const Vector &a, const Vector &b) {return a.x * b.y - a.y * b.x;}
    
    bool polar_cmp(const Line &a, const Line &b)
    {
    	if (fabs(atan2(a.v.y, a.v.x) - atan2(b.v.y, b.v.x)) > eps)
    		return atan2(a.v.y, a.v.x) < atan2(b.v.y, b.v.x);
    	return (a.v ^ (b.p - a.p)) < 0;
    }
    
    Vector inter(const Line &a, const Line &b)
    {
    	return b.p + b.v * (((b.p - a.p) ^ a.v) / (a.v ^ b.v));
    }
    
    void input_poly()
    {
    	int m, x[55], y[55];
    	scanf("%d", &m);
    	for (int i = 1; i <= m; i++)
    		scanf("%d%d", &x[i], &y[i]);
    	x[m + 1] = x[1], y[m + 1] = y[1];
    	for (int i = 1; i <= m; i++)
    		a[++nn].p = Vector(x[i], y[i]), a[nn].v = Vector(x[i + 1] - x[i], y[i + 1] - y[i]);
    }
    
    Line q[2333];
    Vector li[2333];
    int top, bottom;
    
    bool valid(const Vector p, const Line &l)
    {
    	return (l.v ^ (p - l.p)) > 0;
    }
    
    void insert(const Line &l)
    {
    	while (top - bottom >= 2 && valid(inter(q[top], q[top - 1]), l) == false)
    		top--;
    	while (top - bottom >= 2 && valid(inter(q[bottom + 1], q[bottom + 2]), l) == false)
    		bottom++;
    	q[++top] = l;
    }
    
    int main()
    {
    	int fuck;
    	scanf("%d", &fuck);
    	for (int i = 1; i <= fuck; i++)
    		input_poly();
    	sort(a + 1, a + 1 + nn, polar_cmp);
    	for (int i = 1; i <= nn; i++)
    		if (i == 1 || fabs(atan2(a[i].v.y, a[i].v.x) - atan2(a[i - 1].v.y, a[i - 1].v.x)) > eps)
    			a[++n] = a[i];
    	for (int i = 1; i <= n; i++)
    		insert(a[i]);
    	while (top - bottom >= 2 && valid(inter(q[top], q[top - 1]), q[bottom + 1]) == false)
    		top--;
    	while (top - bottom >= 2 && valid(inter(q[bottom + 1], q[bottom + 2]), q[top]) == false)
    		bottom++;
    	q[bottom] = q[top];
    	for (int i = bottom; i < top; i++)
    		li[i] = inter(q[i], q[i + 1]);
    	li[top] = li[bottom];
    	double res = 0;
    	for (int i = bottom; i < top; i++)
    		res += (li[i] ^ li[i + 1]);
    	printf("%.3f
    ", res / 2);
    	return 0;
    }
    
  • 相关阅读:
    Python动态展示遗传算法求解TSP旅行商问题
    MOEAD算法中均匀权向量的实现---Python
    HDU 5294 多校第一场1007题 最短路+最小割
    POJ 3261 Milk Patterns sa+二分
    HDU 4292 FOOD 2012 ACM/ICPC Asia Regional Chengdu Online
    CodeForces 201A Clear Symmetry
    POJ 1679 The Unique MST 确定MST是否唯一
    POJ 3268 Silver Cow Party 最短路 基础题
    POJ 2139 SIx Degrees of Cowvin Bacon 最短路 水題
    POJ2229 Sumsets 基礎DP
  • 原文地址:https://www.cnblogs.com/oier/p/10217818.html
Copyright © 2011-2022 走看看