题意就是给你很多个半平面,求半平面交出来的凸包的面积。

半平面交有O(n^2)的算法,就是每次用一个新的半平面去切已有的凸包,更新,这个写起来感觉也不是特别好写。

另外一个O(nlogn)的算法是将半平面交极角排序,然后用一个双端队列去维护半平面交,每次加入一个半平面,根据之前的交点的位置退掉半平面,方法跟凸包非常相像,(不同的是加入队列的时候还要考虑加入半平面会使队首的平面变得无效,因为会有两个while.最后还要考虑最后加入的半平面绕了一圈之后使得队首的半平面变得无效。)其实这里有点不太懂后面再慢慢补一补吧。

下面的代码用的是CLJ的模板,看大神写的模板能学习到很多东西。我对于计算几何还是不太熟悉,因为如何利用cross求很多东西其实都不太熟,例如如何用cross求两直线的交点。还有里面的border的极角排序的<重载,unique去重时需要的==重载。更高深的原理日后慢慢研究。。- -0

#pragma warning(disable:4996)
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <string>
#include <algorithm>
using namespace std; #define maxn 25000
#define eps 1e-8 int n; int dcmp(double x){
return (x > eps) - (x < -eps);
} struct Point
{
double x, y;
Point(){}
Point(double _x, double _y) :x(_x), y(_y){}
Point operator + (const Point &b) const{
return Point(x + b.x, y + b.y);
}
Point operator - (const Point &b) const{
return Point(x - b.x, y - b.y);
}
Point operator *(double d) const{
return Point(x*d, y*d);
}
Point operator /(double d) const{
return Point(x / d, y / d);
}
double det(const Point &b) const{
return x*b.y - y*b.x;
}
double dot(const Point &b) const{
return x*b.x + y*b.y;
}
}; #define cross(p1,p2,p3) ((p2.x-p1.x)*(p3.y-p1.y)-(p3.x-p1.x)*(p2.y-p1.y))
#define crossOp(p1,p2,p3) (dcmp(cross(p1,p2,p3))) Point isSS(Point p1, Point p2, Point q1, Point q2){
double a1 = cross(q1, q2, p1), a2 = -cross(q1, q2, p2);
return (p1*a2 + p2*a1) / (a1 + a2);
} struct Border
{
Point p1, p2;
double alpha;
void setAlpha(){
alpha = atan2(p2.y - p1.y, p2.x - p1.x);
}
bool operator < ( const Border &b) const{
int c = dcmp(alpha - b.alpha);
if (c != 0) return c == 1;
return crossOp(b.p1, b.p2, p1) >= 0;
}
bool operator == (const Border &b) const{
return dcmp(alpha - b.alpha) == 0;
}
}; Point isBorder(const Border &a, const Border &b){
return isSS(a.p1, a.p2, b.p1, b.p2);
} Border border[maxn];
Border que[maxn];
int qh, qt;
// check函数判断的是新加的半平面和由a,b两个半平面产生的交点的方向,若在半平面的左侧返回True
bool check(const Border &a, const Border &b,const Border &me){
Point is = isBorder(a, b);
return crossOp(me.p1, me.p2, is) > 0;
} void convexIntersection()
{
qh = qt = 0;
sort(border, border + n);
n = unique(border, border + n) - border;
for (int i = 0; i < n; i++){
Border cur = border[i];
while (qh + 1 < qt&&!check(que[qt - 2], que[qt - 1], cur)) --qt;
while (qh + 1 < qt&&!check(que[qh], que[qh + 1], cur)) ++qh;
que[qt++]=cur;
}
while (qh + 1 < qt&&!check(que[qt - 2], que[qt - 1], que[qh])) --qt;
while (qh + 1 < qt&&!check(que[qh], que[qh + 1], que[qt-1])) ++qh;
} Point ps[maxn]; int main()
{
while (cin >> n)
{
for (int i = 0; i < n; i++){
scanf("%lf%lf%lf%lf", &border[i].p1.x, &border[i].p1.y, &border[i].p2.x, &border[i].p2.y);
}
border[n].p1.x = 0; border[n].p1.y = 0; border[n].p2.x = 10000; border[n].p2.y = 0;
border[n+1].p1.x = 10000; border[n+1].p1.y = 0; border[n+1].p2.x = 10000; border[n+1].p2.y = 10000;
border[n+2].p1.x = 10000; border[n+2].p1.y = 10000; border[n+2].p2.x = 0; border[n+2].p2.y = 10000;
border[n+3].p1.x = 0; border[n+3].p1.y = 10000; border[n+3].p2.x = 0; border[n+3].p2.y = 0;
n = n + 4;
for (int i = 0; i < n; i++){
border[i].setAlpha();
}
convexIntersection();
int cnt = 0;
if (qt - qh <= 2){
puts("0.0"); continue;
}
for (int i = qh; i < qt; i++){
int nxt = i + 1 == qt ? qh : i + 1;
ps[cnt++] = isBorder(que[i], que[nxt]);
}
double area = 0;
for (int i = 0; i < cnt; i++){
area += ps[i].det(ps[(i + 1) % cnt]);
}
area /= 2;
area = fabs(area);
printf("%.1lf\n", area);
}
return 0;
}

POJ2451 Uyuw's Concert(半平面交)的更多相关文章

  1. POJ 2451 Uyuw's Concert (半平面交)

    题目链接:POJ 2451 Problem Description Prince Remmarguts solved the CHESS puzzle successfully. As an awar ...

  2. POJ2451 Uyuw's Concert (半平面交)

    POJ2451  给定N个半平面 求他们的交的面积. N<=20000 首先参考 POJ1279 多边形的核 其实就是这里要求的半平面交 但是POJ1279数据较小 O(n^2)的算法 看起来是 ...

  3. [poj2451]Uyuw's Concert

    半平面交滴裸题,但是要求nlogn,练练手 #include<iostream> #include<cstdio> #include<cmath> #include ...

  4. poj2451Uyuw's Concert(半平面交)

    链接 逆时针给出线段,如果模板是顺时针的修改下系数的符号进行平面交即可. #include <iostream> #include<cstdio> #include<cs ...

  5. poj 2451 Uyuw's Concert (半平面交)

    2451 -- Uyuw's Concert 继续半平面交,这还是简单的半平面交求面积,不过输入用cin超时了一次. 代码如下: #include <cstdio> #include &l ...

  6. poj 2451 Uyuw's Concert(半平面交)

    Uyuw's Concert Time Limit: 6000MS   Memory Limit: 65536K Total Submissions: 8580   Accepted: 3227 De ...

  7. 半平面交总结and模板

    博客原文地址:http://blog.csdn.net/xuechelingxiao/article/details/40859973 这两天刷了POJ上几道半平面交,对半平面交有了初步的体会,感觉半 ...

  8. poj 2451 Uyuw's Concert

    [题目描述] Remmarguts公主成功地解决了象棋问题.作为奖励,Uyuw计划举办一场音乐会,地点是以其伟大的设计师Ihsnayish命名的巨大广场. 这个位于自由三角洲联合王国(UDF,Unit ...

  9. 【POJ 3525】Most Distant Point from the Sea(直线平移、半平面交)

    按逆时针顺序给出n个点,求它们组成的多边形的最大内切圆半径. 二分这个半径,将所有直线向多边形中心平移r距离,如果半平面交不存在那么r大了,否则r小了. 平移直线就是对于向量ab,因为是逆时针的,向中 ...

随机推荐

  1. 菜鸟学习Hibernate——配置Hibernate环境

    一.概念. Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库.既然学习Hibernate那么第 ...

  2. Linux环境下的编译,链接与库的使用

    参考博客: http://www.cnblogs.com/qytan36/archive/2010/05/25/1743955.html http://m.blog.csdn.net/article/ ...

  3. Java之NIO传输数据

    NIO可谓陈词旧调,不值一提. 但之前都是泛泛而谈, 现在深入应用才知道秘诀所在. 对于SocketChannel有read()与write(),但由于"非阻塞IO"本质, 这二个 ...

  4. mac 系统开发android,真机调试解决方案

    1.确保你的android设备真正链接到电脑上了,我在这里遇到过坑,弄了好久,才发现能充电的线,确无法传递数据过去.所以不要以为随便拿一根线,能充电,就可以传递数据了,我就是这么傻傻的拿了根不能用的数 ...

  5. Asp.NET网站Session浅谈

    .NET网站在Web.config的<configuration>下<system.web>下<sessionState>配置session. sessionSta ...

  6. [小技巧]让C#的空值处理变得更优雅

    参考 http://www.codeproject.com/Articles/739772/Dynamically-Check-Nested-Values-for-IsNull-Values?msg= ...

  7. Mac nginx PCRE install ngnix

    1 下载:pcre-8.12.tar.gz ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre 2 sudo tar xvfz pcre-8.1 ...

  8. cocos2dx中导演的职责有哪些?

    1.一个游戏里面只有一个导演,因此采用了单例的设计模式,用getInstance方法来获得 2.游戏中导演负责openGL ES的初始化,场景的切换,游戏的暂停继续(相当于拍电影的ka),节点坐标与世 ...

  9. 寻找“水王”--c++

    一.题目与设计思路 三人行设计了一个灌水论坛.信息学院的学生都喜欢在上面交流灌水,传说在论坛上有一个“水王”,他不但喜欢发帖,还会回复其他ID发的每个帖子.坊间风闻该“水王”发帖数目超过了帖子数目的一 ...

  10. 【Valid Parentheses】cpp

    题目: Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine if the ...