poj Grandpa's Estate

来源:互联网 发布:宽带提速软件 编辑:程序博客网 时间:2024/06/05 18:32

题意:爷爷的农场是一个用大钉打点确定凸包,但是有些大钉不见了, 输入现存的N个刚好构成凸包的点, 求这些点能否唯一确定一个凸包。
分析:1.如果凸包边上至少含有一点, 则凸包可以唯一确定, 因为在凸包边上的外围加上一个点, 则凸包会多出一个不在凸包上的点。
   2. 如果点都共线, 则外围凸包上可以随便放一个或多个点, 凸包不确定。


#include <iostream>#include <cstdio>#include <queue>#include <algorithm>#include <complex>#include <ctime>#include <cstdlib>#include <cstring>#include <string>#define INF 1e8#define MAX (int)1e6+ 5#define eps 1e-8using namespace std;int T, n;inline int next(const int &i, const int &n){ return (i + 1) % n;}inline int cmpd(double x){ return x > eps ? 1: (x < -eps? -1 : 0 );}struct Point{    int x, y;    Point (){}    Point (const int &xx, const int &yy):x(xx),y(yy){}    friend int det(const Point &a, const Point &b){        return a.x * b.y - a.y * b.x;    }    friend int dot(const Point &a, const Point &b){        return a.x * b.x + a.y * b.y;    }    Point operator - (const Point &a)const{        return Point(x - a.x, y - a.y);    }    bool operator == (const Point &a)const {        return a.x == x && a.y == y;    }    bool operator < (const Point &a)const {        return x < a.x || ( x == a.x && y < a.y);    }    void in(){        cin>>x>>y;    }    void out(){        cout<<x<<y<<endl;    }};struct Line{    Point s, t;    Line(const Point &ss, const Point &tt):s(ss), t(tt){}    bool isInLineEx(const Point &p){        int res1 = det(p - s, p - t);///共线        int res2 = dot(p - s, p - t);///不在两端        return res1 == 0 && res2 <  0;    }};struct Polygon{    vector<Point> p;    Polygon(){}    Polygon(const vector<Point> &ip):p(ip){}    double area(){        int n = p.size();        double ans = 0;        for(int i  = 0; i < n; i++){            ans += det(p[i], p[next(i, n)]);        }        ans /= 2.0;        return ans;    }    bool hull(vector<Point> &t){        int n = t.size(), m = 0;        p.resize(n);        sort(t.begin(), t.end());        t.erase(unique(t.begin(), t.end()), t.end());//去重复        n = t.size();        bool isThree = false;        for(int i = 0; i < n ;i++){            while( m > 1 && det(p[m - 1] - p[m - 2], p[m - 1] - t[i]) <= 0 )m--;//replaced            p[m++] = t[i];        }        int k = m;        for(int  i = n - 2; i >= 0; i--){            while(m > k && det(p[m - 1] -  p[m - 2], p[m - 1] -  t[i]) <= 0)m--;            p[m++] = t[i];        }        p.resize(m);/// 0 - (m - 1) - 0//        for(int i = 0; i < m - 1; i++){//            p[i].out();//        }        if(cmpd(area()) == 0){return false;}        for(int i = 0; i < m - 1; i++){            bool isFind = false;            Line line(p[i], p[i + 1]);            for(int j = 0; j < n; j++){                if(line.isInLineEx(t[j]) ){                    isFind = true;                    break;                }            }if(!isFind){return false;}        }        return true;    }};int main(){    cin>>T;    while(T--){        cin>>n;        vector<Point>temp;        Point t;        for(int i = 0; i < n; i++){            t.in(); temp.push_back(t);        }        Polygon pg;        if(pg.hull(temp))puts("YES");        else puts("NO");    }    return 0;}/*560 00 10 21 02 01 1*/


原创粉丝点击