Cod sursa(job #2766682)

Utilizator betybety bety bety Data 2 august 2021 20:45:06
Problema Triangulare Scor 100
Compilator cpp-64 Status done
Runda Arhiva ICPC Marime 3.3 kb
#include <bits/stdc++.h>
using namespace std;
ifstream in("triangulare.in");
ofstream out("triangulare.out");
const int kMaxN = 55;
const double kEps = 1e-7;
typedef pair<double, double> Point;
typedef pair<Point, Point> Segment;
int N;
vector< Point > polygon, triangulation;
bool IsZero(const double& x)
{
    return fabs(x) < kEps;
}
double Determinant(const Point& a, const Point& b, const Point& c)
{
    return (b.first - a.first)*(c.second - a.second) - (b.second - a.second)*(c.first - a.first);
}
bool IsInsidePolygon(const Point& p)
{
    Point q(1000000, rand() % 1000000);
    bool isInside = false;
    for (int i = 0; i < N; ++i)
    {
        int j = (i + 1) % N;
        if (Determinant(p, polygon[i], polygon[j])*Determinant(q, polygon[i], polygon[j]) > 0
                && Determinant(polygon[i], p, q)*Determinant(polygon[j], p, q) < -kEps)
            isInside ^= true;
    }
    return isInside;
}
bool IntIntervals(double left1, double right1, double left2, double right2)
{
    if (left1 > left2)
    {
        swap(left1, left2);
        swap(right1, right2);
    }
    return right1 - left2 > kEps;
}
bool IntSegments(const Segment& a, const Segment& b)
{
    if (IsZero(Determinant(a.first, a.second, b.first)) && IsZero(Determinant(a.first, a.second, b.second)))
    {
        if (IntIntervals( min(a.first.first, a.second.first), max(a.first.first, a.second.first),
                                min(b.first.first, b.second.first), max(b.first.first, b.second.first) )
                || IntIntervals( min(a.first.second, a.second.second), max(a.first.second, a.second.second),
                                       min(b.first.second, b.second.second), max(b.first.second, b.second.second) ))
            return true;
        else
            return false;
    }
    return (Determinant(a.first, a.second, b.first)*Determinant(a.first, a.second, b.second) < -kEps
            && Determinant(b.first, b.second, a.first)*Determinant(b.first, b.second, a.second) < -kEps);
}
bool CheckCut(Segment cutSegment)
{
    for (int i = 0; i < N; ++i)
    {
        if (IntSegments(cutSegment, Segment(polygon[i], polygon[(i + 1) % N])))
            return false;
    }
    for (auto& it : triangulation)
    {
        if (IntSegments(cutSegment, Segment(polygon[it.first], polygon[it.second])))
            return false;
    }
    return IsInsidePolygon(Point( (cutSegment.first.first + cutSegment.second.first)/2,
                                  (cutSegment.first.second+ cutSegment.second.second)/2 ));
}
int main()
{
    srand(time(NULL));
    int testCount;
    in >> testCount;
    while (testCount--)
    {
        in >> N;
        polygon.resize(N);
        for (auto& it : polygon)
            in >> it.first >> it.second;
        triangulation.clear();
        for (int i = 0; i < N; ++i)
        {
            for (int j = (i + 2) % N; (j + 1) % N != i; j = (j + 1) % N)
            {
                if (CheckCut(Segment(polygon[i], polygon[j])))
                    triangulation.push_back({ min(i, j), max(i, j) });
            }
        }
        sort(triangulation.begin(), triangulation.end());
        for (auto it : triangulation)
            out << it.first << ' ' << it.second << '\n';
    }
    return 0;
}
//Trust me, I'm the Doctor!