# UVa 1304 - Art Gallery

396人阅读 评论(0)

1. 是一个有点裸的半平面交的题目 ， 不需要用O(nlogn)复杂度的算法

2. 你可以先写写白书上的一个CurPolygon的函数(在半平面交的最开始处)

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <string>
#include <vector>
#include <deque>
#include <stack>
#include <algorithm>

using namespace std;
double eps = 1e-10;
int dcmp(double a){ return fabs(a)<eps?0:(a<0?-1:1); }

struct points
{
double x , y;
points(double x = 0 , double y = 0):x(x),y(y){}
bool operator <(const points& b)const { return dcmp(x-b.x)<0 || (dcmp(x-b.x)==0 && dcmp(y-b.y)<0); }
};

typedef points Vector;
typedef vector<points> Polygon;

Vector operator -(Vector a , Vector b) { return Vector(a.x-b.x , a.y-b.y); }
Vector operator +(Vector a , Vector b) { return Vector(a.x+b.x , a.y+b.y); }
Vector operator *(Vector a , double b) { return Vector(a.x*b   , a.y*b  ); }
Vector operator /(Vector a , double b) { return Vector(a.x/b   , a.y/b  ); }
bool operator ==(Vector a , Vector b) { return dcmp(a.x-b.x)==0 && dcmp(a.y-b.y)==0; }
bool operator !=(Vector a , Vector b) { return dcmp(a.x-b.x) || dcmp(a.y-b.y); }
double Dot(Vector a , Vector b) { return a.x*b.x+a.y*b.y; }
double Cross(Vector a , Vector b) { return a.x*b.y-a.y*b.x; }
double Length(Vector a) { return sqrt(Dot(a, a)); }
double angle(Vector a){ return atan2(a.y, a.x); }
double angle(Vector a , Vector b) { return acos(Dot(a, b)/Length(a)/Length(b)); }

Polygon p , ne;
points a[2000];

points LinesIntersection(points p , Vector v , points q , Vector w)
{
Vector u = p-q;
double t = Cross(w, u)/Cross(v, w);
return p+v*t;
}

bool OnSegment(points p , points a , points b)
{
return dcmp(Dot(a-p, b-p))<0;
}

Polygon CutAPolygon(points a , points b , Polygon p)
{
int n = (int)p.size();
ne.clear();
for(int i=0;i<p.size();i++)
{
points c = p[i];
points d = p[(i+1)%n];
if(dcmp(Cross(b-a, c-a))>=0) ne.push_back(c);
if(dcmp(Cross(b-a, c-d)))
{
points e = LinesIntersection(a, b-a, c, d-c);
if(OnSegment(e, c, d)) ne.push_back(e);
}
}
return ne;
}

double PolygonArea(Polygon p)
{
double res = 0;
int n = (int)p.size();
for(int i=1;i<n-1;i++) res+= Cross(p[i]-p[0], p[(i+1)]-p[0]);
return res/2.0;
}

int main(int argc, char *argv[]) {

int t , n;
cin>>t;
while(t-- && cin>>n)
{
for(int i=0;i<n;i++)
for(int i=0;i<n;i++) p.push_back(a[i]);
if(PolygonArea(p)<0)
{
reverse(a, a+n);
reverse(p.begin(), p.end());
}
for(int i=0;i<n;i++)
p = CutAPolygon(a[i], a[(i+1)%n], p);

printf("%.2lf\n",fabs(PolygonArea(p)));
}

return 0;
}

PS: 貌似博主的正确程序被弄掉了 ， 这个程序不一定是正确的 ， 但是稍稍修改初始化半平面的代码就可以了 ， (也就是初始的那个平面不用题目给的多边形，而是自己加一个很大的矩形) ， 或者联系我讨论: QQ 812483101

0
0

* 以上用户言论只代表其个人观点，不代表CSDN网站的观点或立场
个人资料
• 访问：70326次
• 积分：1750
• 等级：
• 排名：千里之外
• 原创：99篇
• 转载：0篇
• 译文：0篇
• 评论：19条
评论排行
最新评论