Cod sursa(job #1910814)

Utilizator hevelebalazshevele balazs hevelebalazs Data 7 martie 2017 18:26:02
Problema Triangulare Scor 0
Compilator c Status done
Runda Arhiva ICPC Marime 4.05 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 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 type[50];
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;
}

const float PI = 3.141592653589;

int between(float a1, float a, float a2) {
    if (a1 < 0) a1 += 2 * PI;
    if (a < 0) a += 2 * PI;
    if (a2 < 0) a2 += 2 * PI;

    if (a1 > a2) {
        float tmp = a1;
        a1 = a2;
        a2 = tmp;
    }

    return (a1 < a && a < a2);
}

int good1(int i, float x, float y) {
    int prev = i ? (i - 1) : (pointn - 1);
    int next = (i == pointn - 1) ? 0 : (i + 1);

    float aprev = atan2(pointy[prev] - pointy[i], pointx[prev] - pointx[i]);
    float anext = atan2(pointy[next] - pointy[i], pointx[next] - pointx[i]);
    float axy = atan2(y - pointy[i], x - pointx[i]);

    if (between(aprev, axy, anext)) {
        return (type[i] == 1);
    }
    else {
        return (type[i] == -1);
    }
}

int good(int i, int j) {
    int goodi = good1(i, pointx[j], pointy[j]);
    int goodj = good1(j, pointx[i], pointy[i]);

    return (goodi && goodj);
}

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]);
        }

        int polydir = (area > 0) ? (1) : (-1);

        for (i = 0; i < pointn; ++i) {
            int prev = i ? (i - 1) : (pointn - 1);
            int next = (i < pointn - 1) ? (i + 1) : 0;

            int dir = direction(pointx[prev], pointy[prev], pointx[i], pointy[i], pointx[next], pointy[next]);

            if (dir != polydir) type[i] = 1;
            else type[i] = -1;
        }

        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;

                if (!good(i, j)) continue;

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

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

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