题目链接:http://poj.org/problem?id=2451
题意:在一个[0,10000]*[0,10000]的矩形里面做线性规划,让你求线性规划后的区域部分的面积
解析:半平面交求面积,直接套模板
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
const double eps = 1e-6;
const int maxn = 1e5+100;
int dblcmp(double x)
{
if(fabs(x)<eps)
return 0;
return x>0?1:-1;
}
struct point
{
double x,y;
point () {}
point(double _x,double _y)
{
x = _x;
y = _y;
}
}ans[maxn];
struct line
{
point s,e;
double angle;
line() {}
line(point _s,point _e)
{
s = _s;
e = _e;
angle = atan2(e.y-s.y,e.x-s.x);
}
}l[maxn],deq[maxn];
int head,tail,it;
double x_mul(point p0,point p1,point p2)
{
return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}
point cross(line u,line v)
{
point ret = u.s;
double t = ((u.s.x-v.s.x)*(v.s.y-v.e.y)
-(u.s.y-v.s.y)*(v.s.x-v.e.x))
/ ((u.s.x-u.e.x)*(v.s.y-v.e.y)
-(u.s.y-u.e.y)*(v.s.x-v.e.x));
ret.x += (u.e.x-u.s.x)*t, ret.y += (u.e.y-u.s.y)*t;
return ret;
}
bool cmp(line u,line v)
{
//极角排序
int tmp = dblcmp(u.angle-v.angle);
if(tmp)
return tmp>0;
return dblcmp(x_mul(u.s,v.s,v.e))>0;
//Clockwise:大于0取向量左半部分为半平面,小于0,取右半部分
}
bool judge(line l1,line l2,line l3)
{
point p = cross(l2,l3);
return dblcmp(x_mul(p,l1.s,l1.e))<0;
//Clockwise:大于小于符号与上面cmp()中注释处相反
}
void HPI(line l[],int n)
{
//nlgn算法
sort(l,l+n,cmp);
int tmp = 1;
for(int i=1;i<n;i++)
{
if(dblcmp(l[i].angle-l[tmp-1].angle)!=0)
l[tmp++] = l[i];
}
n = tmp;
deq[0] = l[0],deq[1] = l[1];
head = 0,tail = 1;
for(int i=2;i<n;i++)
{
while(head<tail && judge(l[i],deq[tail-1],deq[tail]))
tail--;
while(head<tail && judge(l[i],deq[head+1],deq[head]))
head++;
deq[++tail] = l[i];
}
while(head<tail && judge(deq[head],deq[tail-1],deq[tail]))
tail--;
while(head<tail && judge(deq[tail],deq[head+1],deq[head]))
head++;
if(head==tail)
return ;
it = 0;
for(int i=head;i<tail;i++)
ans[it++] = cross(deq[i],deq[i+1]);
if(tail>head+1)
ans[it++] = cross(deq[head],deq[tail]);
}
bool isThereACore()
{
//判断多边形是否有核
if(tail-head>1)
return true;
return false;
}
double getArea(point p[],int n)
{
//求线性规划面积
double area = 0;
for(int i=1;i<n-1;i++)
area += x_mul(p[i+1],p[0],p[i]);
return fabs(area)/2.0;
}
int main(void)
{
int n;
while(~scanf("%d",&n))
{
n += 4;
l[0] = (line){(point){0, 10000}, (point){0, 0}};
l[1] = (line){(point){10000, 10000}, (point){0, 10000}};
l[2] = (line){(point){10000, 0}, (point){10000, 10000}};
l[3] = (line){(point){0, 0}, (point){10000, 0}};
for(int i = 4; i < n; ++i)
{
point p1,p2;
scanf("%lf%lf%lf%lf",&p1.x,&p1.y,&p2.x,&p2.y);
l[i] = line(p1,p2);
}
HPI(l,n);
printf("%.1f\n", getArea(ans,it));
}
return 0;
}