半平面交板子错了?
查看原帖
半平面交板子错了?
833124
BIOS楼主2023/10/24 21:43
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int N = 200;
const double eps = 1e-10, pi = acos(-1);
typedef pair<double, double> PDD;
#define x first
#define y second
PDD ans[N], p[N];
struct Line
{
    PDD st, ed;
} line[N];
int n, top, q[N], kase;
PDD operator-(PDD a, PDD b) { return {a.x - b.x, a.y - b.y}; }
PDD operator*(PDD a, double t) { return {a.x * t, a.y * t}; }
PDD operator+(PDD a, PDD b) { return {a.x + b.x, a.y + b.y}; }
double cross(PDD a, PDD b) { return a.x * b.y - a.y * b.x; }
double area(PDD a, PDD b, PDD c) { return cross(b - a, c - a); }
double get_angle(Line a) { return atan2(a.ed.y - a.st.y, a.ed.x - a.st.x); }
int dcmp(double x, double y)
{
    if (fabs(x - y) < eps)
        return 0;
    return x < y ? -1 : 1;
}
bool cmp(Line a, Line b)
{
    double A = get_angle(a), B = get_angle(b);
    if (!dcmp(A, B))
        return area(a.st, a.ed, b.ed) < 0;
    return A < B;
}
int sign(double x)
{
    if (fabs(x) < eps)
        return 0;
    return x < 0 ? -1 : 1;
}
PDD gli(PDD p, PDD v, PDD q, PDD w)
{
    auto u = p - q;
    double t = cross(w, u) / cross(v, w);
    return p + v * t;
}
PDD gli(Line a, Line b)
{
    return gli(a.st, a.ed - a.st, b.st, b.ed - b.st);
}
bool on_right(Line a, Line b, Line c)
{
    auto o = gli(b, c);
    return sign(area(a.st, a.ed, o)) <= 0;
}
bool half()
{
    sort(line, line + n, cmp);
    int hh = 0, tt = -1, k = 0;
    for (int i = 0; i < n; i++)
    {
        if (i && !dcmp(get_angle(line[i]), get_angle(line[i - 1])))
            continue;
        while (hh < tt && on_right(line[i], line[q[tt - 1]], line[q[tt]]))
            tt--;
        while (hh < tt && on_right(line[i], line[q[hh]], line[q[hh + 1]]))
            hh++;
        q[++tt] = i;
    }
    while (hh < tt && on_right(line[q[hh]], line[q[tt - 1]], line[q[tt]]))
        tt--;
    while (hh < tt && on_right(line[q[tt]], line[q[hh]], line[q[hh + 1]]))
        hh++;
    q[++tt] = q[hh];
    for (int i = hh; i < tt; i++)
        ans[k++] = gli(line[q[i]], line[q[i + 1]]);
    double res = 0;
    for (int i = 1; i + 1 < k; i++)
        res += area(ans[0], ans[i], ans[i + 1]);
    return fabs(res) > eps;
}
int main()
{
    while (cin >> n, n)
    {
        if (kase)
            printf("\n");
        printf("Room #%d:\n", ++kase);
        for (int i = n - 1; i >= 0; i--)
            cin >> p[i].x >> p[i].y;
        for (int i = 0; i < n; i++)
            line[i] = {p[i], p[(i + 1) % n]};
        if (half())
            cout << "Surveillance is possible.\n";
        else
            cout << "Surveillance is impossible.\n";
    }
}

感觉思路和题解一样,顺时针输入的点也逆序处理了。这两天写的三个半平面交全都部分AC,到底是不是半平面交板子的问题?

2023/10/24 21:43
加载中...