题目链接:http://poj.org/problem?id=1279
Time Limit: 1000MS Memory Limit: 10000K

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

Problem solving report:

Description: 求出可以看到画廊所有地方的区域面积。
Problem solving: 首先利用半平面交求出交点,再利用这些交点求出面积。注意判断是顺时针输入还是逆时针。在POJ里面一直不知道为啥G++过不了,C++能过。。。后来才发现G++里面printf不认%lf,认%f。

Accepted Code:

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int MAXN = 1550;
const double eps = 1e-16;
typedef struct point {
    double x, y;
}vect;
struct line {
    vect p;
    point u, v;
    bool operator < (const line& s) const {
        return atan2(s.p.y, s.p.x) > atan2(p.y, p.x);
    }
};
vect operator - (const point a, const point b) {
    vect p;
    p.x = a.x - b.x;
    p.y = a.y - b.y;
    return p;
}
double dist(const point a, const point b) {
    return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
int pnz(double x) {
    return x < -eps ? -1 : x > eps ? 1 : 0;
}
double Cross(const vect a, const vect b) {
    return a.x * b.y - a.y * b.x;
}
int Onleft(const point p, const line l) {
    return pnz(Cross(l.p, p - l.u));
}
point Inter(const line a, const line b) {
    point p;
    double t = Cross(b.p, a.u - b.u) / Cross(a.p, b.p);
    p.x = a.u.x + t * a.p.x;
    p.y = a.u.y + t * a.p.y;
    return p;
}
double Area(const point p[], int n) {
    double area = 0;
    for (int i = 1; i < n - 1; i++)
        area += Cross(p[i] - p[0], p[i + 1] - p[0]);
    return area / 2;
}
double Halfplane(line Sline[], int n) {
    point Spt[MAXN];
    int Q[MAXN] = {0};
    int l = 0, r = 0;
    sort(Sline, Sline + n);
    for (int i = 1; i < n; i++) {
        while (l < r && Onleft(Spt[r - 1], Sline[i]) < 0)
            r--;
        while (l < r && Onleft(Spt[l], Sline[i]) < 0)
            l++;
        Q[++r] = i;
        if (!pnz(Cross(Sline[i].p, Sline[Q[r - 1]].p))) {
            r--;
            if (Onleft(Sline[i].u, Sline[Q[r]]) > 0)
                Q[r] = i;
        }
        else Spt[r - 1] = Inter(Sline[i], Sline[Q[r - 1]]);
    }
    while (l < r && Onleft(Spt[r - 1], Sline[Q[l]]) < 0)
        r--;
    while (l < r && Onleft(Spt[l], Sline[Q[r]]) < 0)
        l++;
    if (r - l < 2)
        return 0;
    Spt[r] = Inter(Sline[Q[l]], Sline[Q[r]]);
    return Area(Spt + l, r - l + 1);
}
int main() {
    int n, t;
    point p[MAXN];
    line Sl[MAXN], Sline[MAXN];
    scanf("%d", &t);
    while (t--) {
        scanf("%d", &n);
        for (int i = 0; i < n; i++)
            scanf("%lf%lf", &p[i].x, &p[i].y);
        if (pnz(Area(p, n)) < 0)//利用面积的正负判断顺逆
            reverse(p, p + n);
        p[n] = p[0];
        for (int i = 0; i < n; i++) {
            Sl[i].u = p[i];
            Sl[i].v = p[i + 1];
            Sl[i].p = p[i + 1] - p[i];
        }
        printf("%.2f\n", Halfplane(Sl, n));
    }
    return 0;
}