Cod sursa(job #2071655)

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

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

#define MAXC 1000000
#define MAXN 800

std::unordered_map < long long, int > mp;
int x[MAXN + 1], y[MAXN + 1];
int n, ans[MAXN + 1], v[MAXN + 1];
bool viz[MAXN + 1], gr[MAXN + 1];
int c[MAXN + 1], r, a[MAXN + 1];

inline bool solve(int x) {
    int k = 0, i = x;
    while (viz[x] == 0 && x) {
        viz[x] = i;
        a[++k] = x;
        x = v[x];
    }
    if (x == 0) {
        if (k % 2) return 0;
        else for (int j = 1; j <= k; j += 2) ans[a[j]] = 1, ans[a[j + 1]] = 2;
    } else if (viz[x] != i) {
        if (k % 2) a[++k] = x;
        for (int j = 1; j <= k; j += 2) ans[a[j]] = 1, ans[a[j + 1]] = 2;
    } else {
        if (k == 1) return 0;
        int p = 0;
        while (a[p + 1] != x)
            p++;
        if (p % 2) p++;
        for (int j = 1; j <= p; j += 2) ans[a[j]] = 1, ans[a[j + 1]] = 2;
        c[++r] = x;
    }
    return 1;
}

inline bool ciclu(int x) {
    int s = x, k = 0, p = 1;
    do {
        v[++k] = x;
        if (ans[x]) p = k;
        x = v[x];
    } while(x != s);
    for (int i = 1; i <= k; i++) {
        if (i % 2 == p % 2) ans[v[i]] = 2;
        else if (ans[v[i]] == 2) return 0;
        else ans[v[i]] = 1;
    }
    return 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;
    r = 0;
    for (int i = 1; i <= n; i++)
        if (gr[i] == 0)
            ok &= solve(i);
    for (int i = 1; i <= n; i++)
        if (viz[i] == 0)
            ok &= solve(i);
    if (!ok) return ;

    for (int i = 1; i <= r; i++)
        ok &= ciclu(c[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) {
    for (; c; c--) {
        a ^= b ^= a ^= b;
        b *= -1;
    }
}

int bai(int x) {
    if (x == 0) return 0;
    int u = bai(x + 1);
    u += bool(u % 3 == u % 2) + 1;
    return u;
}

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

    for (int i = 1; i <= n; i++) {
        fscanf(fin, "%d%d", &x[i], &y[i]);
        int &a = mp[(1LL << 30) * x[i] + y[i]];
        if (a) return 1;
        else a = 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;
                v[j] = mp[(1LL << 30) * a + b];
                cnt += bool(v[j]);
            }
            if (cnt >= n / 2)
                check();
        }
    }

    return bai(1);
}