Grandpa‘s Estate POJ - 1228(凸包+稳定凸包+坑点)

总结&收获

  1. 这是柴老板给我们的题,翻译过来之后真的很容易理解错[捂脸],补提尽量看原题。(有时候真的是翻译的坑,百密总有一疏)。

题目

传送门

  1. 题意:给定一些凸包上的点(点都在某个凸包上),问凸包是否唯一。
  2. 题解:唯一,当且仅当凸包的每条边上都给了三个点即以上。(两个点的话,可能直接相连,也可能不直接相连,就不能确定)。
  3. 代码
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <string>
// #define int long long
#define dbg(x) cout << #x << "===" << x << endl
using namespace std;
const int N = 1000 + 10;
const double eps = 1e-8;
int sgn(double x) {
    if (fabs(x) < eps) return 0;
    return (x < 0) ? -1 : 1;
}
struct Point {
    double x, y;
    Point() {}
    Point(double _x, double _y) { x = _x, y = _y; }
    void input() { scanf("%lf%lf", &x, &y); }
    bool operator<(const Point &b) const {
        if (sgn(y - b.y) == 0) return sgn(x - b.x) < 0;
        return sgn(y - b.y) < 0;
    }
    Point operator-(const Point &b) const { return Point(x - b.x, y - b.y); }
    double operator^(const Point &b) const { return x * b.y - y * b.x; }
} p[N], mi;
double cross(Point a, Point b, Point c) { return (b - a) ^ (c - a); }
double dis(Point a, Point b) {
    return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
int n;
bool cmp(Point a, Point b) {
    double t = cross(mi, a, b);
    if (sgn(t == 0)) return sgn(dis(mi, a) - dis(mi, b)) < 0;
    return sgn(t) > 0;
}
struct polygon {
    Point p[N];
    int n;
} a;
//由a数组求凸包传给 P ———— 没想到求凸包这么简单,之前想得太难了,艹
// Point *a,我们传送的是a的地址,函数中可以改变数组。a[]呢?
void getconvex(Point *a, int n, polygon &convex) {
    // Point mi = a[0];
    mi = a[0];
    for (int i = 1; i < n; i++) mi = min(mi, a[i]);
    sort(a, a + n, cmp);  //极角排序:求凸包的准备工作
    int top = 0;          // top模拟栈顶
    convex.p[top] = a[0];
    convex.p[++top] = a[1];
    for (int i = 2; i < n; i++) {
        while (top > 0 &&
               (sgn(cross(convex.p[top - 1], convex.p[top], a[i])) <= 0))
            top--;
        convex.p[++top] = a[i];
    }
    convex.n = top + 1;
    // dbg(convex.n);
    // for (int i = 0; i < convex.n; i++) {
    // cout << ">>>" << i << " " << convex.p[i].x << " " << convex.p[i].y
    //  << endl;
    // }
}

signed main() {
    int T;
    cin >> T;
    while (T--) {
        scanf("%d", &n);
        for (int i = 0; i < n; i++) p[i].input();
        getconvex(p, n, a);
        bool f = true;
        int cnt = 0;
        for (int i = 0; i < a.n; i++) {
            cnt = 0;
            for (int j = 0; j < n; j++) {
                if (sgn(cross(a.p[i], a.p[(i + 1) % a.n], p[j])) == 0) cnt++;
                if (cnt == 3) break;
            }
            if (cnt < 3) {
                f = false;
                break;
            }
        }
        if (a.n <= 2) f = false;
        puts(f ? "YES" : "NO");
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值