poj 1264 SCUD Busters

来源:互联网 发布:爱淘宝广场舞套装秋冬 编辑:程序博客网 时间:2024/05/16 07:05
题意:给出一个k个王国, 每个由Ni个点的确定的凸包确定。之后给出多个炮弹, 如果炮弹落在凸包里, 该王国被停电,王国没有重合面积。问被停电的面积。

分析:简单多边形面积, 点和凸包的关系。


#include <iostream>#include <cstdio>#include <queue>#include <algorithm>#include <complex>#include <ctime>#include <cstdlib>#include <cstring>#include <string>#define INF 1e8#define MAX (int)1e1+ 5#define eps 1e-8using namespace std;int cmpd(double x){ return x > eps ? 1 : ( x < -eps ? -1 : 0);}struct Point{    double x, y;    Point(){}    Point(const double &a, const double &b):x(a), y(b){}    Point operator + (const Point &a)const {        return Point (x + a.x, y + a.y);    }    Point operator - (const Point &a)const {        return Point(x - a.x, y - a.y);    }    Point operator / (const double &a)const {        return Point(x / a, y / a);    }    bool operator < (const Point &a)const {        return x < a.x || ( x == a.x && y < a.y);    }    bool operator == (const Point&a)const {        return a.x == x && a.y == y;    }    friend double dot(const Point &a, const Point &b)  {        return a.x* b.x + a.y * b.y;    }    friend double det(const Point &a,  const Point &b){        return a.x * b.y - a.y * b.x;    }};inline int next(const int &i, const int &n){return (i + 1) % n;}struct Polygon{    vector<Point>p;    //direc area    Polygon(){}    Polygon(const vector<Point> &tp):p(tp){}    double getArea(){        int n = p.size();        double ans = 0;        for(int i = 0; i < n; i++){            ans += det(p[i], p[next(i, n)]);        }        return ans / 2;    }    //获取凸包    void hull(vector<Point> &t){        sort(t.begin(), t.end());        t.erase(unique(t.begin(), t.end()), t.end());        int n = t.size();        p.resize(n);        int m = 0;        for(int i = 0; i < n; i++){            while(m > 1 && cmpd(det(p[m - 1] - p[m - 2], t[i] - p[m - 2])) <= 0)m--;            p[m++]  = t[i];        }        int k = m;        for(int i = n - 2; i >= 0; i--){            while( m > k && cmpd(det(p[m - 1] - p[m - 2], t[i] - p[m - 2])) <= 0)m--;            p[m++] = t[i];        }        p.resize(m);        if(m)p.resize(m - 1);    }    //不包含边界, O(n)funkin    bool isContain(const Point &a){        int n = p.size();        for(int i = 0; i < n;i++){            if(cmpd(det(p[i] - a, p[next(i, n)] - a)) == 0)return false;        }        int sign = 0;        for(int i = 0; i < n; i++){            int tsign = cmpd(det(p[i] - a, p[next(i, n)] - a));            if(tsign){                if(sign){                    if(tsign != sign)return false;                }else{                    sign = tsign;                }            }        }        return true;    }    //不含边界Log(n)    bool isContainOlogN(const Point &b){        int n = p.size();//        cout<<"funking enter"<<endl;        Point g = (p[0]  + p[ n / 3] + p[n * 2 / 3] ) / 3.0;        int l = 0, r = n;        while(l + 1 < r){//            cout<<"funking"<<endl;            int mid = (l + r) >> 1;            double k = det(p[l] - g, p[mid] - g);            double res1 = det(p[l] - g, b - g);            double res2 = det(p[mid] - g, b - g);            if(cmpd(k) > 0){                if( cmpd(res1) >= 0 && cmpd(res2) < 0){                    r  = mid;                }else {                    l = mid;                }            }else {                if(cmpd(res1) < 0 && cmpd(res2)  >= 0){                    l  = mid;                }else {                    r  = mid;                }            }        }        r %= n;        int z = cmpd( det(p[r] - b, p[l] - b) ) ;        if(z < 0)return true;//0 边界 1外面kamo        return false;    }}pg[MAX];int k = 0;bool v[MAX];void ruint(double x, double y){    for(int i  = 0; i < k; i++){        if(!v[i]){            if(pg[i].isContain(Point(x, y))){                v[i] = true;            }        }    }}void cacu(){    double ans = 0;    for(int i = 0; i < k; i++){        if(v[i]){            ans += fabs(pg[i].getArea());        }    }    printf("%.2f\n", ans);}int main(){    int n;    while(cin>>n, n != -1){        Point t;        vector<Point>kingdom;        for(int i = 0; i < n; i++){            cin>>t.x>>t.y;            kingdom.push_back(t);        }        pg[k++].hull(kingdom);    }    double x, y;    while(cin>>x>>y){        ruint(x, y);    }    cacu();    return 0;}

  

原创粉丝点击