BZOJ-2618 [CQOI2006]凸多边形

半平面交模版题。。

#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <cctype>
#include <algorithm>
#define rep(i, l, r) for(int i=l; i<=r; i++)
#define clr(x, c) memset(x, c, sizeof(x))
#define maxn 1000
//#define double long double
#define linf 1e15
using namespace std;
typedef long long ll;
inline int read()
{
	int x=0, f=1; char ch=getchar();
	while (!isdigit(ch)) {if (ch==‘-‘) f=-1; ch=getchar();}
	while (isdigit(ch)) x=x*10+ch-‘0‘, ch=getchar();
	return x*f;
}
struct P{double x, y;} p[maxn];
P operator - (P a, P b){return (P){a.x-b.x, a.y-b.y};}
double operator * (P a, P b){return a.x*b.y-b.x*a.y;}
struct line{P a, b; double ang;} l[maxn], a[maxn], q[maxn];
bool operator < (line a, line b){if (a.ang==b.ang) return (a.b-a.a)*(b.a-a.a)>0; return a.ang<b.ang;}

inline P inter(line a, line b)
{
	double k1=(b.b-a.a)*(a.b-a.a), k2=(a.b-a.a)*(b.a-a.a), t=k2/(k1+k2);
	return (P){b.a.x+t*(b.b.x-b.a.x), b.a.y+t*(b.b.y-b.a.y)};
}
inline bool jud(line x, line y, line v){return (inter(x, y)-v.a)*(v.b-v.a)>0;}
int n, m, cnt;
int main()
{
	n=read();
	rep(i, 1, n)
	{
		int k=read();
		rep(j, 1, k) p[j].x=read(), p[j].y=read(); p[k+1]=p[1];
		rep(j, 1, k) l[++m].a=p[j], l[m].b=p[j+1];
	}
	rep(i, 1, m) l[i].ang=atan2(l[i].b.y-l[i].a.y, l[i].b.x-l[i].a.x);
	sort(l+1, l+1+m);
	rep(i, 1, m)
		a[l[i].ang!=a[cnt].ang ? ++cnt : cnt]=l[i];
	int L=1, R=0; q[++R]=a[1]; q[++R]=a[2];
	rep(i, 3, cnt)
	{
		while (L<R && jud(q[R-1], q[R], a[i])) R--;
		while (L<R && jud(q[L+1], q[L], a[i])) L++;
		q[++R]=a[i];
	}
	while (L<R && jud(q[R-1], q[R], q[L])) R--;
	while (L<R && jud(q[L+1], q[L], q[R])) L++;
	if (R-L<2) {puts("0.000"); return 0;}
	cnt=0; q[R+1]=q[L]; rep(i, L, R) p[++cnt]=inter(q[i], q[i+1]);
	double ans=0;
	rep(i, 1, cnt-1) ans+=p[i].x*p[i+1].y; ans+=p[cnt].x*p[1].y;
	rep(i, 2, cnt) ans-=p[i].x*p[i-1].y; ans-=p[1].x*p[cnt].y;
	if (ans<0) ans*=-1;
	printf("%.3lf", ans/2);
	return 0;
}
时间: 2024-10-26 05:34:33

BZOJ-2618 [CQOI2006]凸多边形的相关文章

BZOJ 2618 CQOI2006 凸多边形 半平面交

题目大意:给定n个凸多边形,求交集的面积 时隔多年我终于把完整的半平面交搞出来了--真尼玛艰辛-- 曾经写了一发 RE到死 于是就搁置0.0 今天写一发又是WA到死的节奏-- 不多说直接上代码 其实刘汝佳同学写麻烦了 每次插入一个半平面之后不用两端都删的 只删一端 最后再处理两端的部分就行 300题留念--切了道模板题也不错 #include <cmath> #include <cstdio> #include <cstring> #include <iostre

●BZOJ 2618 [Cqoi2006]凸多边形

题链: http://www.lydsy.com/JudgeOnline/problem.php?id=2618 题解: 计算几何,半平面交. 给出一些凸包,求面积交. 把所有边都取出来,直接办平面交就好.    原来dcmp也不能滥用,之前把所有的大于小于比较都用了dcmp函数,导致错误. (以后除了double型判等,其它时候尽量不用dcmp好了) 代码: #include<cmath> #include<cstdio> #include<cstring> #inc

【BZOJ 2618】 2618: [Cqoi2006]凸多边形 (半平面交)

2618: [Cqoi2006]凸多边形 Description 逆时针给出n个凸多边形的顶点坐标,求它们交的面积.例如n=2时,两个凸多边形如下图: 则相交部分的面积为5.233. Input 第一行有一个整数n,表示凸多边形的个数,以下依次描述各个多边形.第i个多边形的第一行包含一个整数mi,表示多边形的边数,以下mi行每行两个整数,逆时针给出各个顶点的坐标. Output 输出文件仅包含一个实数,表示相交部分的面积,保留三位小数. Sample Input 2 6 -2 0 -1 -2 1

BZOJ 2618 CQOI 2006 凸多边形 半平面交

题目大意:给出n个凸多边形,求这些多边形的面积的交. 思路:犯傻了..以后看到凸多边形第一时间就要想到半平面交啊..多明显啊,半天愣着没想出来. CODE: #include <cmath> #include <cstdio> #include <iomanip> #include <cstring> #include <iostream> #include <algorithm> #define MAX 6100 #define E

BZOJ2618 [Cqoi2006]凸多边形

那个叫啥,半平面交... 第一次写于是只能按照惯例,orz hzwer去~~~ 把一个凸多边形搞成好多条线段,于是题目就变成了一堆线段的半平面交... 怎么感觉比仙人掌还简单一点的说...就是有点长 1 /************************************************************** 2 Problem: 2618 3 User: rausen 4 Language: C++ 5 Result: Accepted 6 Time:0 ms 7 Memo

BZOJ 2222: [Cqoi2006]猜数游戏【神奇的做法,傻逼题,猜结论】

2222: [Cqoi2006]猜数游戏 Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 604  Solved: 260[Submit][Status][Discuss] Description 佳佳和明明玩一个猜数游戏.佳佳想一个1~n之间的整数,明明每次可以随便猜一个数.从第二次猜测起,佳佳告诉明明本次猜测的数和上次猜测的数相比哪个更接近.B表示本次猜测的数更接近,W表示上次猜测的数更接近.如果两次猜测的接近程度一样,则既可回答B也可回答W.

【bzoj2618】[Cqoi2006]凸多边形 半平面交

题目描述 逆时针给出n个凸多边形的顶点坐标,求它们交的面积.例如n=2时,两个凸多边形如下图: 则相交部分的面积为5.233. 输入 第一行有一个整数n,表示凸多边形的个数,以下依次描述各个多边形.第i个多边形的第一行包含一个整数mi,表示多边形的边数,以下mi行每行两个整数,逆时针给出各个顶点的坐标. 输出 输出文件仅包含一个实数,表示相交部分的面积,保留三位小数. 样例输入 2 6 -2 0 -1 -2 1 -2 2 0 1 2 -1 2 4 0 -3 1 -1 2 2 -1 0 样例输出

【半平面交】bzoj2618 [Cqoi2006]凸多边形

#include<cstdio> #include<cmath> #include<algorithm> using namespace std; #define EPS 0.0000001 #define N 511 typedef double db; const db PI=acos(-1.0); struct Point{db x,y;}; typedef Point Vector; Vector operator - (const Point &a,c

bzoj2618[Cqoi2006]凸多边形 半平面交

这是一道半平面交的裸题,第一次写半平面交,就说一说我对半平面交的理解吧. 所谓半平面交,就是求一大堆二元一次不等式的交集,而每个二元一次不等式的解集都可以看成是在一条直线的上方或下方,联系直线的标准方程就可以得出.于是乎这些不等式就可以转化为一些半平面,求的就是半平面交. 而半平面交不可能交出凹多边形(因为凹多边形的定义是有一条边所在的直线能把该多边形分成若干块...YY一下就知道这是不可能的),这是一个十分优美的性质,正类似于凸包(写法也是有些相似的),但半平面交可能交出无界,于是可以加四条类