简单几何(求凸包点数) POJ 1228 Grandpa's Estate

 

题目传送门

题意:判断一些点的凸包能否唯一确定

分析:如果凸包边上没有其他点,那么边想象成橡皮筋,可以往外拖动,这不是唯一确定的。还有求凸包的点数<=2的情况一定不能确定。

 

/************************************************
* Author        :Running_Time
* Created Time  :2015/11/4 星期三 10:24:45
* File Name     :POJ_1228.cpp
 ************************************************/

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <cstring>
#include <cmath>
#include <string>
#include <vector>
#include <queue>
#include <deque>
#include <stack>
#include <list>
#include <map>
#include <set>
#include <bitset>
#include <cstdlib>
#include <ctime>
using namespace std;

#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
typedef long long ll;
const int N = 1e5 + 10;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const double EPS = 1e-10;
const double PI = acos (-1.0);
int dcmp(double x)  {
    if (fabs (x) < EPS) return 0;
    else    return x < 0 ? -1 : 1;
}
struct Point    {
    double x, y;
    Point () {}
    Point (double x, double y) : x (x), y (y) {}
    Point operator - (const Point &r) const {
        return Point (x - r.x, y - r.y);
    }
    bool operator < (const Point &r) const  {
        return x < r.x || (x == r.x && y < r.y);
    }
    bool operator == (const Point &r) const {
        return dcmp (x - r.x) == 0 && dcmp (y - r.y) == 0;
    }
};
typedef Point Vector;
Point read_point(void)  {
    double x, y;    scanf ("%lf%lf", &x, &y);
    return Point (x, y);
}
double dot(Point a, Point b)    {
    return a.x * b.x + a.y * b.y;
}
double cross(Vector A, Vector B)    {
    return A.x * B.y - A.y * B.x;
}
bool on_seg(Point p, Point a, Point b)    {
    return dcmp (cross (a - p, b - p)) == 0 && dcmp (dot (a - p, b - p)) < 0;
}

/*
    凸包边上无点:<=    凸包边上有点:<
*/
vector<Point> convex_hull(vector<Point> ps)   {
    sort (ps.begin (), ps.end ());
    int n = ps.size (), k = 0;
    vector<Point> qs (n * 2);
    for (int i=0; i<n; ++i) {
        while (k > 1 && cross (qs[k-1] - qs[k-2], ps[i] - qs[k-1]) <= 0)    k--;
        qs[k++] = ps[i];
    }
    for (int t=k, i=n-2; i>=0; --i) {
        while (k > t && cross (qs[k-1] - qs[k-2], ps[i] - qs[k-1]) <= 0)     k--;
        qs[k++] = ps[i];
    }
    qs.resize (k - 1);
    return qs;
}

int main(void)    {
    int T;  scanf ("%d", &T);
    while (T--) {
        int n;  scanf ("%d", &n);
        vector<Point> ps;
        for (int i=0; i<n; ++i) ps.push_back (read_point ());
        if (n == 1) {
            puts ("NO");    continue;
        }
        vector<Point> qs = convex_hull (ps);
        if (qs.size () == n || qs.size () <= 2)    {
            puts ("NO");    continue;
        }
        qs.push_back (qs[0]);
        int m = qs.size ();
        bool flag = false;
        for (int i=0; i<m-1; ++i)   {
            flag = false;
            for (int j=0; j<ps.size (); ++j)    {
                if (ps[j] == qs[i] || ps[j] == qs[i+1]) continue;
                if (on_seg (ps[j], qs[i], qs[i+1])) {
                    flag = true;    break;
                }
            }
            if (!flag)  break;
        }
        if (flag)   puts ("YES");
        else    puts ("NO");
    }

   //cout << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << " s.\n";

    return 0;
}

 

posted @ 2015-11-04 11:38  Running_Time  阅读(454)  评论(0编辑  收藏  举报