Cod sursa(job #2071671)

Utilizator alexpetrescuAlexandru Petrescu alexpetrescu Data 20 noiembrie 2017 21:22:21
Problema Overlap Scor 84
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.24 kb
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <unordered_map>

FILE *fin = fopen("overlap.in", "r"), *fout = fopen("overlap.out", "w");

#define MAXN 800
#define LIM 15360000
#define T 151

int mp[LIM];
int x[MAXN + 1], y[MAXN + 1];
int n, ans[MAXN + 1], v[MAXN + 1];
bool viz[MAXN + 1], gr[MAXN + 1];

inline bool solve(int x) {
    int cul = 1;
    while (x) {
        viz[x] = 1;
        ans[x] = cul;
        cul = 3 - cul;
        x = v[x];
    }
    return (cul == 1);
}

inline bool ciclu(int x) {
    int cul = 1;
    while (viz[x] == 0) {
        ans[x] = cul;
        cul = 3 - cul;
        viz[x] = 1;
        x = v[x];
    }
    return (cul == 1);
}

inline void check() {
    memset(gr, 0, sizeof gr);
    for (int i = 1; i <= n; i++)
        if (v[i])
            gr[v[i]] = 1;

    memset(ans, 0, sizeof ans);
    memset(viz, 0, sizeof viz);
    bool ok = 1;
    for (int i = 1; i <= n; i++)
        if (gr[i] == 0)
            ok &= solve(i);
    if (!ok) return ;

    for (int i = 1; i <= n; i++)
        if (viz[i] == 0)
            ok &= ciclu(i);
    if (!ok) return ;

    for (int i = 1; i <= n; i++)
        fprintf(fout, "%d\n", ans[i]);
    exit(0);
}

inline void rot(int &a, int &b, int c) {
    if (c >= 2) {
         a = -a;
         b = -b;
         c -= 2;
    }
    if (c) {
        a ^= b ^= a ^= b;
        b = -b;
    }
}

int main() {
    fscanf(fin, "%d", &n);

    for (int i = 1; i <= n; i++) {
        fscanf(fin, "%d%d", &x[i], &y[i]);
        mp[T * x[i] + y[i]] = i;
    }

    for (int p = 0; p < 4; p++) {
        int sa = x[1], sb = y[1];
        rot(sa, sb, p);
        for (int i = 2; i <= n; i++) {
            int sx = x[i] - sa, sy = y[i] - sb;
            v[1] = i;
            int cnt = 1;
            for (int j = 2; j <= n; j++) {
                int a = x[j], b = y[j];
                rot(a, b, p);
                a += sx;
                b += sy;
                if (T * a + b >= 0 && T * a + b < LIM)
                    v[j] = mp[T * a + b];
                else v[j] = 0;
                cnt += bool(v[j]);
            }
            if (cnt >= n / 2)
                check();
        }
    }

    return 1;
}