POJ2451Uyuw's Concert

来源:互联网 发布:程序员被黑 编辑:程序博客网 时间:2024/06/06 09:03

思路:刚开始没看懂题意,其实和求多边形的核类似,这是求半平面的交。开始我感觉用复数表示点,很不习惯,以前从没用过。

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;//2451Accepted3344K704MSC++3383B2013-06-04 19:03:55typedef 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:310000 10000 0 500010000 5000 5000 100000 5000 5000 071 1 5 15 1 5 45 4 1 61 6 1 11 2 2 15 4 1 45 4 1 2output:54166666.77.5**/