Cod sursa(job #1753235)

Utilizator mariusn01Marius Nicoli mariusn01 Data 6 septembrie 2016 10:41:00
Problema Overlap Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.55 kb
#include <fstream>
#include <algorithm>
#include <cstring>

#define DIM 810

using namespace std;

struct punct {
    int x;
    int y;
    int p;
};

int cmp(const punct &a, const punct &b) {
    if (a.x == b.x)
        return a.y < b.y;
    else
        return a.x < b.x;
}

punct P[DIM], r;
int T[DIM], F[DIM], C[DIM*DIM], D[DIM];
int minx, miny, trax, tray, N, i, j, poz, u;

punct rotate(punct a, int u) {
    punct r;
    if (u == 0)
        return a;
    if (u == 1) {
        r.x = -a.y;
        r.y = a.x;
        return r;
    }
    if (u == 2) {
        r.x = -a.x;
        r.y = -a.y;
        return r;
    } else {
        r.x = a.y;
        r.y = -a.x;
        return r;
    }
}

inline int minim (int a, int b) {
    return (a < b ? a : b);
}

int search(int p, int u, punct r) {
    int m;
    while (p<=u) {
        m = (p+u)/2;
        if (P[m].x == r.x && P[m].y == r.y)
            return m;
        if (P[m].x < r.x || (P[m].x == r.x && P[m].y < r.y))
            p = m+1;
        else
            u = m-1;
    }
    return 0;
}

int cuplaj(int s) {
    int i, m, nr;

    memset(F, 0, sizeof(F));

    for (i=1;i<=N;i++)
        if (D[i] + T[i] == 0)
            return 0;

    for (i=1;i<=N;i++)
        if (D[i] == 0) {
            j = i;
            m = 1;
            nr = 0;
            do {
                F[j] = m;
                nr++;
                j = T[j];
                if (m == 1)
                    m = 2;
                else
                    m = 1;
                if (F[j] != 0 && F[j] !=m )
                    return 0;
            } while (F[j] == 0 && j!=0);
            if (nr%2 == 1)
                return 0;
        }
    for (i=1;i<=N;i++)
        if (F[i] == 0) {
            j = i;
            m = 1;

            nr = 0;
            do {
                F[j] = m;
                nr++;
                j = T[j];
                if (m == 1)
                    m = 2;
                else
                    m = 1;
                if (F[j] != 0 && F[j] !=m)
                    return 0;
            } while (F[j] == 0);

            if (nr%2 == 1)
                return 0;
        }

    for (i=1;i<=N;i++)
        if (F[i] == 0)
            return 0;

    return 1;
}

ofstream g("overlap.out");

void sol() {
    for (int i = 1; i<=N; i++)
        g<<F[i]<<"\n";
}

int main() {
    ifstream f("overlap.in");
    f>>N;
    for (i=1;i<=N;i++) {
        f>>P[i].x>>P[i].y;
        P[i].p = i;
    }

    for (i=1;i<=N;i++) {
        miny = minim(miny, P[i].y);
        minx = minim(minx, P[i].x);

    }

    for (i=1;i<=N;i++) {
        P[i].x += (minx + 1);
        P[i].y += (miny + 1);
    }

    sort(P+1, P+N+1, cmp);

    for (i=2;i<=N;i++) {
        //cuplez P[1] cu P[i]
        for (u = 0; u<=3; u++) {

            memset(T, 0, sizeof(T));
            memset(D, 0, sizeof(D));

            r = rotate(P[1], u);
            trax = P[i].x - r.x;
            tray = P[i].y - r.y;
            T[P[1].p] = P[i].p;
            D[P[i].p] = 1;


            for (j=2;j<=N;j++){
                r = rotate(P[j], u);
                r.x = r.x + trax;
                r.y = r.y + tray;
                poz = search(1, N, r);
                if (poz!=0) {
                    T[P[j].p] = P[poz].p;
                    D[P[poz].p] = 1;
                }
            }
            if (cuplaj(P[1].p)) {
                sol();
                return 0;
            }
        }
    }
    return 0;
}