Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 4300 | Accepted: 1849 |
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 思考:求多边形的核,给出的多边形点的顺序可能是逆序也可能是顺序,给出的最大数的范围16-bit integer type。用C++提交AC,用G++提交WA。有时间学习一下两则的不同。 半平面问题的第一题,很兴奋!#include <iostream> #include <cstdio> #include <algorithm> #include <cmath> #include <vector> #include <complex> using namespace std; const int maxn = 2000; const double inf = 1e5; const double eps = 1e-10; //1279 Accepted 348K 0MS C++ 3482B 2013-06-04 09:13:50 struct point { double x; double y; point(){} point( double a, double b):x(a), y(b){} friend point operator - (const point &a, const point &b) { return point(a.x-b.x, a.y-b.y); } }; double det(const point &a, const point &b) { return a.x*b.y - a.y*b.x; } struct polygon { int n; point a[maxn]; }; //把直线化为一般式。 struct halfPlane { double a, b, c; halfPlane(point p, point q) { a = q.y - p.y; b = p.x - q.x; c = det(q, p); } }; struct polygon_convex { vector <point> P; }; double calc(halfPlane &L, point &a) { return a.x*L.a + a.y*L.b + L.c; } point Intersect(point &a, point &b, halfPlane &L) { point res; double t1 = calc(L, a), t2 = calc(L, b); res.x = (t2*a.x - t1*b.x)/(t2-t1); res.y = (t2*a.y - t1*b.y)/(t2-t1); return res; } //将一个凸多边形和一个半平面交。 polygon_convex cut(polygon_convex &a, halfPlane &L) { int n = a.P.size(); polygon_convex res; for(int i = 0; i < n; i++) { if(calc(L, a.P[i])<-eps) { res.P.push_back(a.P[i]); } else { int j; j = i - 1; if(j < 0) j = n-1; if(calc(L, a.P[j])<-eps) res.P.push_back(Intersect(a.P[j], a.P[i],L)); j = i + 1; if(j==n) j = 0; if(calc(L, a.P[j])<-eps) res.P.push_back(Intersect(a.P[i], a.P[j], L)); } } return res; } //参数为一个多边形, 返回一个凸多边形。 polygon_convex core(polygon &a) { polygon_convex res; res.P.clear(); //清空容器. res.P.push_back(point(-inf, -inf)); res.P.push_back(point(inf, -inf)); res.P.push_back(point(inf, inf)); res.P.push_back(point(-inf, inf)); int n = a.n; if(n==2) { halfPlane L(a.a[0], a.a[1]); return res = cut(res, L); } for(int i = 0; i < n ; i++) { halfPlane L(a.a[i], a.a[(i+1)%n]);//多边形循环产生n个半平面。 // printf("%.2lf, %.2lf, %.2lf\n", L.a, L.b, L.c); res = cut(res, L);//用产生的半平面调用cut去一次次切割。 } return res;//还回凸多边形. } //如果多边形是顺时针给出,则改变方向. polygon init(polygon v) { int n = v.n; double area = 0; for(int i = 1; i < n-1; i++) { area += det(v.a[i]-v.a[0], v.a[i+1]-v.a[0]); } if(area < 0) { polygon temp; temp.n = n; temp.a[0] = v.a[0]; for(int i = n-1; i >= 1; i--) { temp.a[n-i] = v.a[i]; } return temp; } return v; } double get_area(polygon_convex v) { double area = 0; int n = v.P.size(); for(int i = 1; i < n-1; i++) { area += det(v.P[i]-v.P[0], v.P[i+1]-v.P[0]); } return area/2; } int main() { polygon v; point tmp; int T; int n; scanf("%d", &T); while(T--) { scanf("%d", &n); v.n = 0; for(int i = 0; i < n; i++) { scanf("%lf%lf", &tmp.x, &tmp.y); v.a[i] = tmp; v.n++; //别忘了。 } v = init(v); polygon_convex ans = core(v); double result = get_area(ans); printf("%.2lf\n", result); } return 0; }