POJ 1279 Art Gallery [半平面交]

Art Gallery

Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 7324   Accepted: 2936

Description

The art galleries of the new and very futuristic building of the Center for Balkan Cooperation have the form of polygons (not necessarily convex). When a big exhibition is organized, watching over all of the pictures is a big security concern. Your task is that for a given gallery to write a program which finds the surface of the area of the floor, from which each point on the walls of the gallery is visible. On the figure 1. a map of a gallery is given in some co-ordinate system. The area wanted is shaded on the figure 2.  

Input

The number of tasks T that your program have to solve will be on the first row of the input file. Input data for each task start with an integer N, 5 <= N <= 1500. Each of the next N rows of the input will contain the co-ordinates of a vertex of the polygon ? two integers that fit in 16-bit integer type, separated by a single space. Following the row with the co-ordinates of the last vertex for the task comes the line with the number of vertices for the next test and so on.

Output

For each test you must write on one line the required surface - a number with exactly two digits after the decimal point (the number should be rounded to the second digit after the decimal point).

Sample Input

1
7
0 0
4 4
4 7
9 7
13 -1
8 -6
4 -4

Sample Output

80.00

Source

Southeastern Europe 2002


傻逼裸题该死isLSI中sgn的括号打错了RE了无数次40多分钟啊气死我了

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
using namespace std;
typedef long long ll;
const int N=1505;
const double INF=1e9;
const double eps=1e-8;
inline int read(){
    char c=getchar();int x=0,f=1;
    while(c<‘0‘||c>‘9‘){if(c==‘-‘)f=-1; c=getchar();}
    while(c>=‘0‘&&c<=‘9‘){x=x*10+c-‘0‘; c=getchar();}
    return x*f;
}

inline int sgn(double x){
    if(abs(x)<eps) return 0;
    else return x<0?-1:1;
}

struct Vector{
    double x,y;
    Vector(double a=0,double b=0):x(a),y(b){}
    bool operator <(const Vector &a)const{
        return sgn(x-a.x)<0||(sgn(x-a.x)==0&&sgn(y-a.y)<0);
    }
};
typedef Vector Point;
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 sgn(a.x-b.x)==0&&sgn(a.y-b.y)==0;}
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;}

struct Line{
    Point s,t;
    Line(){}
    Line(Point a,Point b):s(a),t(b){}
};
bool isLSI(Line l1,Line l2){
    Vector v=l1.t-l1.s,u=l2.s-l1.s,w=l2.t-l1.s;
    return sgn(Cross(v,u))!=sgn(Cross(v,w));
}
Point LI(Line a,Line b){
    Vector v=a.s-b.s,v1=a.t-a.s,v2=b.t-b.s;
    double t=Cross(v2,v)/Cross(v1,v2);
    return a.s+v1*t;
}

void iniPolygon(Point p[],int &n,double inf){
    n=0;
    p[++n]=Point(inf,inf);
    p[++n]=Point(inf,-inf);
    p[++n]=Point(-inf,-inf);
    p[++n]=Point(-inf,inf);
}
Point t[N];int tn;
void CutPolygon(Point p[],int &n,Point a,Point b){//get the left of a->b
    tn=0;
    Point c,d;
    for(int i=1;i<=n;i++){
        c=p[i],d=p[i%n+1];
        if(sgn(Cross(b-a,c-a))>=0) t[++tn]=c;
        if(isLSI(Line(a,b),Line(c,d)))
            t[++tn]=LI(Line(a,b),Line(c,d));
    }
    n=tn;for(int i=1;i<=n;i++) p[i]=t[i];
}

double PolygonArea(Point p[],int n){
    double s=0;
    for(int i=2;i<n;i++) s+=Cross(p[i]-p[1],p[i+1]-p[1]);
    return abs(s/2);
}

int n,m;
Point p[N],q[N];
int main(int argc, const char * argv[]){
    int T=read();
    while(T--){
        n=read();
        for(int i=1;i<=n;i++) scanf("%lf%lf",&p[i].x,&p[i].y);
        iniPolygon(q,m,INF);
        for(int i=1;i<=n;i++) CutPolygon(q,m,p[i%n+1],p[i]);
        double ans=PolygonArea(q,m);
        printf("%.2lf\n",ans);
    }
}
时间: 2024-08-04 15:15:25

POJ 1279 Art Gallery [半平面交]的相关文章

POJ 1279 Art Gallery 半平面交求多边形核

第一道半平面交,只会写N^2. 将每条边化作一个不等式,ax+by+c>0,所以要固定顺序,方便求解. 半平面交其实就是对一系列的不等式组进行求解可行解. 如果某点在直线右侧,说明那个点在区域内,否则出现在左边,就可能会有交点,将交点求出加入. //#pragma comment(linker, "/STACK:16777216") //for c++ Compiler #include <stdio.h> #include <iostream> #inc

POJ 1279 Art Gallery 半平面交+求多边形核的面积

裸的:半平面交+求多边形核的面积 Art Gallery Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 5735   Accepted: 2419 Description The art galleries of the new and very futuristic building of the Center for Balkan Cooperation have the form of polygons (not

POJ 1279 Art Gallery 半平面交 多边形的核

题意:求多边形的核的面积 套模板即可 #include <iostream> #include <cstdio> #include <cmath> #define eps 1e-18 using namespace std; const int MAXN = 1555; double a, b, c; int n, cnt; struct Point { double x, y; double operator ^(const Point &b) const {

poj 1279 -- Art Gallery (半平面交)

鏈接:http://poj.org/problem?id=1279 Art Gallery Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 5337   Accepted: 2277 Description The art galleries of the new and very futuristic building of the Center for Balkan Cooperation have the form

POJ 1279 Art Gallery(半平面交求多边形核的面积)

题目链接 题意 : 求一个多边形的核的面积. 思路 : 半平面交求多边形的核,然后在求面积即可. #include <stdio.h> #include <string.h> #include <iostream> #include <math.h> using namespace std ; struct node { double x; double y ; } p[1510],temp[1510],newp[1510];//p是最开始的多边形的每个点,

poj 1279 Art Gallery(利用极角计算半平面交)

题意:给出n个点的坐标描述一个多边形画廊.在画廊平面上找到一片表面,从该区域能够看到画廊墙壁上的每一个点: 思路:将这片表面称为多边形的核.核中一点与多边形边界上任意一点的连线都在多边形内部.凸多边形的核为其本身,凹多边形的核为其内部的一部分或不存在: 将多边形的n个顶点转化为n条边的直线方程:逆时针用多边形的边剖分多边形所在平面,保留向里的部分,舍去向外的部分,剩下的即为核: 利用叉积公式计算核面积,即为所求面积: #include<cstdio> #include<cstring&g

POJ 1279 Art Gallery 多边形内核面积

题目大意:按顺序给出一个多边形的顶点,求这个多边形内核的面积.答案保留两位输出. 思路:半平面交.加边的时候要讨论一下第一个点和最后一个点,否则会wa的很惨. CODE: #include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define MAX 1510 #define EPS 1e-8 #define DC

poj 3384 Feng Shui 半平面交的应用 求最多覆盖凸多边形的面积的两个圆 的圆心坐标

题目来源: http://poj.org/problem?id=3384 分析: 用半平面交将多边形的每条边一起向"内"推进R,得到新的多边形(半平面交),然后求多边形的最远两点. 代码如下: const double EPS = 1e-10; const int Max_N = 105 ; struct Point{ double x,y; Point(){} Point(double x, double y):x(x),y(y){} Point operator - (Point

POJ 2451 nlog(n)半平面交裸题。

前言       最近学习C#,不过好在当初考计算机二级学习过C++,刚上手没有对C#感到很恐惧.C#视频也看了几天 了,总感觉不总结一下心里没底,现在跟着我从头走进C#之旅吧.     C#是以后总面向对象的编程语言(OOP),C#是从C和C++派生出来的,主要用于开发可以运行在.NET平台 上的应用程序.随着.NET的发展,C#语言简单.现代.面向对象和类型安全显示了一定的优势.     下面我就介绍一些初学者不太理解的一些东西.   C#有以下突出的特点       (1)语法简洁.不允许