poj 1279 半平面交核面积

Art Gallery

Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 6668   Accepted: 2725

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
/*
poj 1279 半平面交核面积

给你一个多边形的图书馆.要求得到一块地方能看见墙上所有的点,并求出面积
在半平面模板上加个求面积公式即可.
而且输入并没有指定顺时针还是逆时针,可以通过求面积进行判断.

hhh-2016-05-11 21:01:47
*/
#include <iostream>
#include <vector>
#include <cstring>
#include <string>
#include <cstdio>
#include <queue>
#include <cmath>
#include <algorithm>
#include <functional>
#include <map>
using namespace std;
#define lson  (i<<1)
#define rson  ((i<<1)|1)
typedef long long ll;
using namespace std;
const int  maxn = 1510;
const double PI = 3.1415926;
const double eps = 1e-8;

int sgn(double x)
{
    if(fabs(x) < eps) return 0;
    if(x < 0)
        return -1;
    else
        return 1;
}

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);
    }
    double operator ^(const Point &b)const
    {
        return x*b.y-y*b.x;
    }
    double operator *(const Point &b)const
    {
        return x*b.x + y*b.y;
    }
};

struct Line
{
    Point s,t;
    double k;
    Line() {}
    Line(Point _s,Point _t)
    {
        s = _s;
        t = _t;
        k = atan2(t.y-s.y,t.x-s.x);
    }
    Point operator &(const Line &b) const
    {
        Point res = s;
        double ta = ((s-b.s)^(b.s-b.t))/((s-t)^(b.s-b.t));
        res.x += (t.x-s.x)*ta;
        res.y += (t.y-s.y)*ta;
        return res;
    }
};

bool HPIcmp(Line a,Line b)
{
    if(fabs(a.k-b.k) > eps) return a.k<b.k;
    return ((a.s-b.s)^(b.t-b.s)) < 0;
}
Line li[maxn];

double CalArea(Point p[],int n)
{
    double ans = 0;
    for(int i = 0;i < n;i++)
    {
        ans += (p[i]^p[(i+1)%n])/2;
    }
    return ans;
}

double  HPI(Line line[],int n,Point res[],int &resn)
{
    int tot =n;
    sort(line,line+n,HPIcmp);
    tot = 1;
    for(int i = 1; i < n; i++)
    {
        if(fabs(line[i].k - line[i-1].k) > eps)
            line[tot++] = line[i];
    }
    int head = 0,tail = 1;
    li[0] = line[0];
    li[1] = line[1];
    resn = 0;
    for(int i = 2; i < tot; i++)
    {
        if(fabs((li[tail].t-li[tail].s)^(li[tail-1].t-li[tail-1].s)) < eps||
                fabs((li[head].t-li[head].s)^(li[head+1].t-li[head+1].s)) < eps)
            return 0;
        while(head < tail && (((li[tail] & li[tail-1]) - line[i].s) ^ (line[i].t-line[i].s)) > eps)
            tail--;
        while(head < tail && (((li[head] & li[head+1]) - line[i].s) ^ (line[i].t-line[i].s)) > eps)
            head++;
        li[++tail] = line[i];
    }
    while(head < tail && (((li[tail] & li[tail-1]) - li[head].s) ^ (li[head].t-li[head].s)) > eps)
        tail--;
    while(head < tail && (((li[head] & li[head-1]) - li[tail].s) ^ (li[tail].t-li[tail].t)) > eps)
        head++;
    if(tail <= head+1)
        return 0;
    for(int i = head; i < tail; i++)
        res[resn++] = li[i]&li[i+1];
    if(head < tail-1)
        res[resn++] = li[head]&li[tail];

    double tans = 0;
    for(int i = 0;i < resn;i++)
    {
        tans += (res[i]^res[(i+1)%resn])/2;
    }
    return fabs(tans);
}
Point p0;
Point lis[maxn];
Line line[maxn];
double dist(Point a,Point b)
{
    return sqrt((a-b)*(a-b));
}

bool cmp(Point a,Point b)
{
    double t = (a-p0)^(b-p0);
    if(sgn(t) > 0)return true;
    else if(sgn(t) == 0 && sgn(dist(a,lis[0])-dist(b,lis[0])) <= 0)
        return true;
    else
        return false;
}

int main()
{
    //freopen("in.txt","r",stdin);
    int n,T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        for(int i = 0; i < n; i++)
        {
            scanf("%lf%lf",&lis[i].x,&lis[i].y);
        }
        int ans;
        if(CalArea(lis,n) < 0)
            reverse(lis,lis+n);
        for(int i = 0; i < n; i++)
        {
            line[i] = Line(lis[i],lis[(i+1)%n]);
        }
        printf("%.2f\n",HPI(line,n,lis,ans));
    }
    return 0;
}

  

时间: 2024-10-10 12:20:28

poj 1279 半平面交核面积的相关文章

poj 3335 /poj 3130/ poj 1474 半平面交 判断核是否存在 / poj1279 半平面交 求核的面积

1 /*************** 2 poj 3335 点序顺时针 3 ***************/ 4 #include <iostream> 5 #include <cmath> 6 #include <algorithm> 7 using namespace std; 8 const double eps = 1e-8; 9 const double maxn = 0x7f7f7f7f; 10 int dcmp(double x){ 11 if(fabs(

poj 1279 求半平面交的 面积

poj 1279    求半平面交的 面积 题目来源: http://poj.org/problem?id=1279 分析: 求半平面交的 面积 代码如下: const double EPS = 1e-8; const int Max_N = 1505; struct Point{ double x,y; Point(){} Point(double x, double y):x(x),y(y){} Point operator - (Point p){ return Point(x- p.x

POJ 2540 半平面交求可行区域面积

Hotter Colder Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 2343   Accepted: 981 Description The children's game Hotter Colder is played as follows. Player A leaves the room while player B hides an object somewhere in the room. Player

POJ 3335 半平面交求多边形的核

Rotating Scoreboard Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 4899   Accepted: 1946 Description This year, ACM/ICPC World finals will be held in a hall in form of a simple polygon. The coaches and spectators are seated along the ed

POJ 3525 /// 半平面交 模板

题目大意: 给定n,接下来n行逆时针给定小岛的n个顶点 输出岛内离海最远的点与海的距离 半平面交模板题 将整个小岛视为由许多半平面围成 那么以相同的比例缩小这些半平面 一直到缩小到一个点时 那个点就是离海最远的点 #include <cstdio> #include <cmath> #include <vector> #include <algorithm> using namespace std; const double eps=1e-10; doubl

POJ 3525 半平面交+二分

二分所能形成圆的最大距离,然后将每一条边都向内推进这个距离,最后所有边组合在一起判断时候存在内部点 1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 #include <cmath> 6 7 using namespace std; 8 #define N 105 9 #define ll long long 10 #de

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 半平面交+求多边形核的面积

裸的:半平面交+求多边形核的面积 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 半平面交求多边形核

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