bzoj 2618: [Cqoi2006]凸多边形 [半平面交]

2618: [Cqoi2006]凸多边形

半平面交

注意一开始多边形边界不要太大...

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#define y1 y1z
using namespace std;
typedef long long ll;
const double eps = 1e-10, inf = 1e10;
const int N = 1005;

inline int read() {
    char c = getchar(); int x = 0, f = 1;
    while(c < '0' || c > '9') {if(c=='-')f=-1; c=getchar();}
    while(c >= '0' && c <= '9') {x=x*10+c-'0'; c=getchar();}
    return x * f;
}

inline double _abs(double x) {return x < 0 ? -x : x;}
inline int sgn(double x) {return _abs(x) < eps ? 0 : (x < 0 ? -1 : 1);}

struct meow {
	double x, y;
	meow(double x = 0, double y = 0) : x(x), y(y) {}
	bool operator <(const meow &r) const {return sgn(x - r.x) == 0 ? sgn(y - r.y) < 0 : sgn(x - r.x) < 0;}
	void print() {printf("(%lf, %lf)\n", x, y);}
} ;
typedef meow Vector; typedef Vector Point;
meow operator + (meow a, meow b) {return meow(a.x + b.x, a.y + b.y);}
meow operator - (meow a, meow b) {return meow(a.x - b.x, a.y - b.y);}
meow operator * (meow a, double b) {return meow(a.x * b, a.y * b);}
meow operator / (meow a, double b) {return meow(a.x / b, a.y / b);}

double operator * (meow a, meow b) {return a.x * b.x + a.y * b.y;}
double operator ^ (meow a, meow b) {return a.x * b.y - a.y * b.x;}
struct Line {
	Point s, t, v;
	Line() {}
	Line(Point s, Point t) : s(s), t(t) {v = t - s;}
} ;

bool on_left(Point a, Line l) {
	return sgn(l.v ^ (a - l.s)) >= 0;
}
bool is_lsi(Line l1, Line l2) {
	return sgn((l2.s - l1.s) ^ l1.v) != sgn((l2.t - l1.s) ^ l1.v);
}
Point lli(Line l1, Line l2) {
	Point p = l1.s, q = l2.s; Vector u = l1.v, v = l2.v;
	double k = ((q - p) ^ v) / (u ^ v);
	return p + u * k;
}

void ini_polygon(Point *p, int &n) {
	n = 0;
	p[++n] = Point(-inf, -inf);
	p[++n] = Point(inf, -inf);
	p[++n] = Point(inf, inf);
	p[++n] = Point(-inf, inf);
}
void cut_polygon(Point *p, int &n, Line l) {
	Point c, d;
	static Point t[N]; int tn = 0;
	for(int i=1; i<=n; i++) {
		c = p[i], d = p[i%n+1];
		if(on_left(c, l)) t[++tn] = c;
		if(is_lsi(l, Line(c, d))) t[++tn] = lli(l, Line(c, d));
	}
	n = tn;
	for(int i=1; i<=tn; i++) p[i] = t[i];
}
double polygon_area(Point *p, int n) {
	double s = 0;
	for(int i=2; i<n; i++) s += (p[i] - p[1]) ^ (p[i+1] - p[1]);
	return abs(s / 2); 
}
int n, m, pn; Point a[N], p[N];
int main() {
	freopen("in", "r", stdin);
	n = read();
	ini_polygon(p, pn);
	for(int i=1; i<=n; i++) {
		m = read(); 
		for(int i=1; i<=m; i++) scanf("%lf %lf", &a[i].x, &a[i].y);
		for(int i=1; i<=m; i++) cut_polygon(p, pn, Line(a[i], a[i%m+1]));
	}
	//for(int i=1; i<=pn; i++) p[i].print();
	double ans = polygon_area(p, pn);
	printf("%.3lf\n", ans);
}
posted @ 2017-05-13 21:49  Candy?  阅读(400)  评论(0编辑  收藏  举报