Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 4300 | Accepted: 1849 |
Description
Input
Output
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; }