Cod sursa(job #1897425)

Utilizator Andrei1998Andrei Constantinescu Andrei1998 Data 1 martie 2017 13:39:26
Problema Overlap Scor 48
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.55 kb
#include <fstream>
#include <cassert>
#include <vector>
#include <unordered_map>

using namespace std;

const int NMAX = 800 + 5;
const int VALMAX = 100000 + 5;
typedef long long int lint;

int N;

struct Point {
    int x, y;
    Point(int _x = 0, int _y = 0):
        x(_x), y(_y) {}

    Point rotate(int k) {
        if (!k)
            return (*this);
        else if (k == 1)
            return Point(-y, x);
        else if (k == 2)
            return Point(-x, -y);
        else
            return Point(y, -x);
    }

    Point operator+(const Point &arg) const {
        return Point(x + arg.x, y + arg.y);
    }

    Point operator-(const Point &arg) const {
        return Point(x - arg.x, y - arg.y);
    }

    inline lint encode() {
        return 1LL * VALMAX * x + y;
    }
} points[NMAX];

unordered_map <lint, int> Map;
int nxt[NMAX];
int degree[NMAX];
int lastVis[NMAX];

int getPoint(int x, int y) {
    int b = Point(x, y).encode();
    if (Map.count(b))
        return Map[b];
    else
        return 0;
}

int whichSet[NMAX];

int main()
{
    ifstream cin("overlap.in");
    ofstream cout("overlap.out");

    cin >> N;
    Map.max_load_factor(0.5);
    Map.reserve(N);

    for (int i = 1; i <= N; ++ i) {
        cin >> points[i].x >> points[i].y;

        auto it = Map.find(points[i].encode());
        assert(it == Map.end());
        Map[points[i].encode()] = i;
    }

    int t = 0;
    for (int rot = 0; rot < 4; ++ rot) {
        vector <Point> disps;

        for (int i = 1; i <= N; ++ i) {
            disps.push_back(points[i] - points[1].rotate(rot));
            disps.push_back(points[1] - points[i].rotate(rot));
        }

        for (auto d: disps) {
            for (int i = 1; i <= N; ++ i)
                degree[i] = 0;
            for (int i = 1; i <= N; ++ i) {
                Point to = points[i].rotate(rot) + d;
                int index = getPoint(to.x, to.y);
                nxt[i] = index;
                ++ degree[index];
            }

            ++ t;
            bool fail = false;
            for (int i = 1; i <= N; ++ i)
                if (!degree[i]) {
                    int node = i;
                    lastVis[node] = t;
                    whichSet[node] = 1;
                    while (nxt[node]) {
                        whichSet[nxt[node]] = whichSet[node] ^ 3;
                        node = nxt[node];
                        lastVis[node] = t;
                    }

                    if (whichSet[node] == 1) {
                        fail = true;
                        break;
                    }
                }

            if (fail)
                continue;

            for (int i = 1; i <= N; ++ i)
                if (lastVis[i] < t) {
                    int node = i;
                    lastVis[node] = t;
                    whichSet[node] = 1;
                    node = nxt[node];
                    whichSet[node] = 2;

                    while (node != i) {
                        lastVis[node] = t;
                        whichSet[nxt[node]] = whichSet[node] ^ 3;
                        node = nxt[node];
                    }

                    if (whichSet[i] != 1) {
                        fail = true;
                        break;
                    }
                }

            if (!fail) {
                for (int i = 1; i <= N; ++ i)
                    cout << whichSet[i] << '\n';
                return 0;
            }
        }
    }
    return 0;
}