UVA11072 Points

2017年7月31日

给你一组点集合A,另外有 r 个询问,每个询问给出一个点的坐标,问你能否在 A 中找到三个点使得这个点的坐标的坐标在这三个点组成的三角形内.

其实就是求A的凸包,判断这个点是否在凸包内,判断方法是假设询问的这个点在凸包内,如果能够找到凸包上的一个向量,使得这个点在向量的顺时针方向,那么这个点就在凸包外,否则就在凸包内.

#include <bits/stdc++.h>
using namespace std;
struct Point {
    int x, y;
    Point() {}
    Point(int x, int y) : x(x), y(y) {}
    bool operator < (const Point &a) const {
        return x < a.x || x == a.x && y < a.y;
    }
    Point operator - (const Point &a) const {
        return Point(x - a.x, y - a.y);
    }
} a[100005], ch[100005];
int det(Point a, Point b)
{
    return a.x * b.y - a.y * b.x;
}
int convex_hull(int n)
{
    int m = 0;
    sort(a, a + n);
    for (int i = 0; i < n; i++) {
        while (m > 1 && det(ch[m - 1] - ch[m - 2], a[i] - ch[m - 2]) <= 0)
            m--;
        ch[m++] = a[i];
    }
    int k = m;
    for (int i = n - 2; i >= 0; i--) {
        while (m > k && det(ch[m - 1] - ch[m - 2], a[i] - ch[m - 2]) <= 0)
            m--;
        ch[m++] = a[i];
    }
    return n > 1 ? m - 1 : m;
}
int main()
{
    int n, m;
    while (~scanf("%d", &n)) {
        for (int i = 0; i < n; i++) {
            scanf("%d %d", &a[i].x, &a[i].y);
        }
        int num = convex_hull(n);
        scanf("%d", &m);
        while (m--) {
            int x, y;
            scanf("%d %d", &x, &y);
            Point o = Point(x, y);
            int ok = 1;
            for (int i = 0; i < num - 1; i++) {
                if (det(ch[i + 1] - ch[i], o - ch[i]) < 0) {
                    ok = 0;
                    break;
                }
            }
            if (det(ch[0] - ch[num - 1], o - ch[num - 1]) < 0) {
                ok = 0;
            }
            if (ok) {
                puts("inside");
            } else {
                puts("outside");
            }
        }
    }
    return 0;
}

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注