Cod sursa(job #1911738)

Utilizator hevelebalazshevele balazs hevelebalazs Data 7 martie 2017 21:41:53
Problema Triangulare Scor 100
Compilator c Status done
Runda Arhiva ICPC Marime 4.34 kb
#include <stdio.h>
#include <math.h>

int direction(int x1, int y1, int x2, int y2, int x3, int y3) {
    int dx1 = x2 - x1;
    int dy1 = y2 - y1;
    int dx2 = x3 - x2;
    int dy2 = y3 - y2;

    int val = (dx1 * dy2) - (dy1 * dx2);

    if (val < 0) return -1;
    else if (val == 0) return 0;
    else return 1;
}

int cross(int x11, int y11, int x12, int y12,
    int x21, int y21, int x22, int y22) {
    if (x11 == x21 && y11 == y21) return 0;
    if (x11 == x22 && y11 == y22) return 0;

    if (x12 == x21 && y12 == y21) return 0;
    if (x12 == x22 && y12 == y22) return 0;

    int dir1, dir2;

    dir1 = direction(x11, y11, x21, y21, x22, y22);
    dir2 = direction(x12, y12, x21, y21, x22, y22);
    if (dir1 == dir2) return 0;

    dir1 = direction(x21, y21, x11, y11, x12, y12);
    dir2 = direction(x22, y22, x11, y11, x12, y12);
    if (dir1 == dir2) return 0;

    return 1;
}

int pointx[50];
int pointy[50];
int pointn;

int line[50][50];
int last;

int line1[100];
int line2[100];
int linen;

void addline(int point1, int point2) {
    if (line[point1][point2] == last) return;

    line[point1][point2] = last;
    line[point2][point1] = last;

    line1[linen] = point1;
    line2[linen] = point2;
    linen++;
}

int crossany(int x1, int y1, int x2, int y2) {
    int i;
    for (i = 0; i < linen; ++i) {
        int p1 = line1[i];
        int p2 = line2[i];

        if (cross(x1, y1, x2, y2,
                  pointx[p1], pointy[p1], pointx[p2], pointy[p2])) {
            return 1;
        }
    }

    return 0;
}

int inpolyup(float x, float y) {
    int count = 0;
    int i;
    for (i = 0; i < pointn; ++i) {
        int prev = i ? (i - 1) : (pointn - 1);

        if (pointx[i] < x && pointx[prev] < x) continue;
        if (pointx[i] > x && pointx[prev] > x) continue;

        float r = (x - pointx[i]) / (pointx[prev] - pointx[i]);

        float crossy = pointy[i] + r * (pointy[prev] - pointy[i]);

        if (crossy < y) count++;
    }

    return (count % 2 == 1);
}

int inpolyleft(float x, float y) {
    int count = 0;
    int i;
    for (i = 0; i < pointn; ++i) {
        int prev = i ? (i - 1) : (pointn - 1);

        if (pointy[i] < y && pointy[prev] < y) continue;
        if (pointy[i] > y && pointy[prev] > y) continue;

        float r = (y - pointy[i]) / (pointy[prev] - pointy[i]);

        float crossx = pointx[i] + r * (pointx[prev] - pointx[i]);

        if (crossx < x) count++;
    }

    return (count % 2 == 1);
}

int main() {
    freopen("triangulare.in", "r", stdin);
    freopen("triangulare.out", "w", stdout);

    int t;
    scanf("%i", &t);
    while (t--) {
        linen = 0;
        ++last;

        scanf("%i", &pointn);

        int i, j;
        for (i = 0; i < pointn; ++i) {
            scanf("%i%i", &pointx[i], &pointy[i]);
        }

        int area = 0;
        for (i = 0; i < pointn; ++i) {
            j = (i) ? (i - 1) : (pointn - 1);
            addline(i, j);

            area += (pointx[i] * pointy[j]) - (pointy[i] * pointx[j]);
        }

        for (i = 0; i < pointn; ++i) {
            for (j = i + 2; j < pointn; ++j) {

                if (line[i][j] == last) continue;

                int prev = i ? (i - 1) : (pointn - 1);
                int next = i + 1;

                int xi = pointx[i];
                int yi = pointy[i];
                int xj = pointx[j];
                int yj = pointy[j];

                if (crossany(xi, yi, xj, yj)) continue;

                if (xi == xj) {
                    float r = 0.5 / (yj - yi);
                    if (r < 0.0) r = -r;
                    float x = r * xi + (1 - r) * xj;
                    float y = r * yi + (1 - r) * yj;

                    int in = inpolyleft(x, y);

                    if (!inpolyleft(x, y)) continue;
                }
                else {
                    float r = 0.5 / (xj - xi);
                    if (r < 0.0) r = -r;
                    float x = r * xi + (1 - r) * xj;
                    float y = r * yi + (1 - r) * yj;

                    int in = inpolyup(x, y);

                    if (!inpolyup(x, y)) continue;
                }

                addline(i, j);
                printf("%i %i\n", i, j);
            }
        }
    }
    return 0;
}