思路:刚开始没看懂题意,其实和求多边形的核类似,这是求半平面的交。开始我感觉用复数表示点,很不习惯,以前从没用过。
poing a; 然后这样给a赋值a.imag() = 0;用C++提交时就一直CE,然后问冰哥,他说在他的DEV c++上有警告,然后我就改为初始化成员列表
然后就AC啦,还是挺兴奋的!
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <cstdlib> #include <complex> #include <deque> #include <vector> using namespace std; const double eps = 1e-10; const double maxn = 20100; typedef complex<double> point; //2451 Accepted 3344K 704MS C++ 3383B 2013-06-04 19:03:55 typedef pair<point, point> halfplane; vector <halfplane> term(maxn*4);//全局变量保存开始的半平面。 point operator + (const point &a, const point b) { return point(a.real()+b.real(), a.imag()+b.imag()); } point operator - (const point &a, const point b) { return point(a.real()-b.real(), a.imag()-b.imag()); } inline int sgn(double n) { return fabs(n)< eps ? 0 : (n<0 ? -1 : 1); } inline double cross(point a, point b) { return (conj(a)*b).imag(); } inline double dot(point a, point b) { return (conj(a)*b).real(); } //点a在半平面的左侧或在半平面上。 inline double satisfy(point a, halfplane p) { return sgn(cross(a-p.first, p.second-p.first))<=0; } //求半平面交点. point crosspoint(const halfplane &a, const halfplane &b) { double k = cross(b.first-b.second, a.first-b.second); k = k / (k-cross(b.first-b.second, a.second-b.second)); return a.first + (a.second - a.first)*k; } //对给出的半平面排序,arg的范围(-PI, PI] 弧度表示。 bool cmp(const halfplane &a, const halfplane &b) { int res = sgn(arg(a.second-a.first) - arg(b.second - b.first)); return res == 0 ? satisfy(a.first, b) : res < 0; } vector<point> halfplane_intersection(vector<halfplane> v) { sort(v.begin(), v.end(), cmp); deque<halfplane> q; deque<point> ans; q.clear(); ans.clear(); q.push_back(v[0]); for(int i = 1; i < int(v.size()); i++) { if(sgn(arg(v[i].second - v[i].first) - arg(v[i-1].second-v[i-1].first))==0) continue; while(ans.size()>0 && !satisfy(ans.back(), v[i])) { ans.pop_back(); q.pop_back(); } while(ans.size()>0 && !satisfy(ans.front(), v[i])) { ans.pop_front(); q.pop_front(); } ans.push_back(crosspoint(q.back(), v[i])); q.push_back(v[i]); } while(ans.size()>0 && !satisfy(ans.back(), q.front())) { ans.pop_back(); q.pop_back(); } while(ans.size()>0 && !satisfy(ans.front(), q.back())) { ans.pop_front(); q.pop_back(); } ans.push_back(crosspoint(q.back(), q.front())); return vector<point>(ans.begin(), ans.end()); } //求多边形面积。 double get_area(vector<point> v) { int Size = v.size(); double area = 0; for(int i = 1; i < Size-1; i++) { area += cross(v[i]-v[0], v[i+1]-v[0]); } return area/2; } //用成员初始化来初始化平面 void init() { term.clear(); point a(0,0), b(10000, 0), c(10000, 10000), d(0, 10000); term.push_back(halfplane(a, b)); term.push_back(halfplane(b, c)); term.push_back(halfplane(c, d)); term.push_back(halfplane(d, a)); } int main() { int n; double a, b, c, d; //how many halfplane; while(scanf("%d", &n) != EOF) { init(); for(int i = 0; i < n; i++) { scanf("%lf%lf%lf%lf", &a, &b, &c, &d); halfplane tmp(point(a,b), point(c,d));//初始化 term.push_back(tmp); } /* 这样就一顿CE. for(int i = 0; i < n; i++) { scanf("%lf%lf%lf%lf", &a, &b, &c, &d); tmp.first.real() = a; tmp.first.imag() = b; tmp.second.real() = c; tmp.second.imag() = d; term.push_back(tmp); } */ vector <point> result = halfplane_intersection(term); double res = get_area(result); printf("%.1lf\n", res); result.clear(); } return 0; } /** input: 3 10000 10000 0 5000 10000 5000 5000 10000 0 5000 5000 0 7 1 1 5 1 5 1 5 4 5 4 1 6 1 6 1 1 1 2 2 1 5 4 1 4 5 4 1 2 output: 54166666.7 7.5 **/