【 [CQOI2006]凸多边形】暴力半平面交

半平面交总觉得和线性规划莫名的像? https://www.luogu.org/problemnew/show/P4196

题目描述

逆时针给出n个凸多边形的顶点坐标,求它们交的面积。例如n=2时,两个凸多边形如下图: 则相交部分的面积为5.233。

输入输出格式

输入格式: 第一行有一个整数n,表示凸多边形的个数,以下依次描述各个多边形。第i个多边形的第一行包含一个整数mi,表示多边形的边数,以下mi行每行两个整数,逆时针给出各个顶点的坐标。 输出格式: 输出文件仅包含一个实数,表示相交部分的面积,保留三位小数。

输入输出样例

输入样例#1: 复制
2
6
-2 0
-1 -2
1 -2
2 0
1 2
-1 2
4
0 -3
1 -1
2 2
-1 0
输出样例#1: 复制
5.233

说明

100%的数据满足:2<=n<=10,3<=mi<=50,每维坐标为[-1000,1000]内的整数 直接暴力求半平面交O(n^2)裸题。之后再考虑写O(n)半平面交吧。
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<iostream>
#include<cmath>
#include<cassert>
using namespace std;
typedef double db;

const int maxn = 505;
const db eps = 1e-8;
struct pt{
	db x,y;
}s[maxn],r[maxn],t[maxn]; int tot;
pt operator+(pt a,pt b) { return (pt){a.x+b.x,a.y+b.y}; }
pt operator-(pt a,pt b) { return (pt){a.x-b.x,a.y-b.y}; }
pt operator*(db k,pt a) { return (pt){k*a.x,k*a.y}; }
db operator*(pt a,pt b) { return a.x*b.x+a.y*b.y; }
db operator^(pt a,pt b) { return a.x*b.y-a.y*b.x; }
struct line{
	pt p,v;
};
pt getcut(line a,line b) {
	//assert(fabs(aa.v^bb.v)<eps); 
	db k = ( (b.p-a.p)^a.v )/(a.v^b.v);
	return b.p + k*b.v;
}
void CUT(line a) {
	int i,j,k,o=0;
	s[tot+1]=s[1];
	s[0] = s[tot];
	for(int i=1;i<=tot;i++) {
		if(((a.v)^(s[i]-a.p))<eps) {
			if( ((a.v)^(s[i-1]-a.p))>eps) {
				t[++o] = getcut((line){s[i-1],s[i]-s[i-1]},a);
			}
			if( ((a.v)^(s[i+1]-a.p)) > eps) {
				t[++o] = getcut((line){s[i],s[i+1]-s[i]},a);
			}
		} else t[++o] = s[i];
	}
	for(int i=1;i<=o;i++) s[i] = t[i];
	tot = o;
}
int n;
int main() {
	scanf("%d",&n);
	s[1] = (pt){-1e5,-1e5};
	s[2] = (pt){1e5,-1e5};
	s[3] = (pt){1e5,1e5};
	s[4] = (pt){-1e5,1e5};
	tot = 4;
	for(int tim = 1;tim <= n; tim++) {
		int k; scanf("%d",&k);
		for(int i=1;i<=k;i++) {
			scanf("%lf%lf",&r[i].x,&r[i].y);
		}
		r[k+1] = r[1];
		for(int i=1;i<=k;i++) {
			CUT( (line){r[i],r[i+1]-r[i]} );
		}
	}
	db ans = 0;
	s[tot+1] = s[1];
	for(int i=1;i<=tot;i++) {
		ans += (s[i]^s[i+1]);
	}
	printf("%.3lf\n",ans/2);
}
 
posted @ 2019-01-03 13:55  Newuser233  阅读(8)  评论(0编辑  收藏  举报