Cod sursa(job #1770383)

Utilizator killer301Ioan Andrei Nicolae killer301 Data 4 octombrie 2016 10:26:51
Problema Overlap Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.48 kb
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
#include <cmath>

using namespace std;

#define NMAX 815
#define mod 717

const int sinAlfa[4]={0,1,0,-1};
const int cosAlfa[4]={1,0,-1,0};

struct Point{
    int x,y;
    int id;

    void init(int _id){
        scanf("%d %d",&x,&y);
        id = _id;
    }
    void Rot(int k)
    {
        int _x = x, _y = y;
        x = cosAlfa[k]*_x - sinAlfa[k]*_y;
        y = sinAlfa[k]*_x + cosAlfa[k]*_y;
    }
    void Shift(Point shift)
    {
        x += shift.x;
        y += shift.y;
    }
    bool operator==(const Point& other)
    {
        return (x==other.x)&&(y==other.y);
    }
};

struct Hash
{
    vector < Point > C[mod];
    int abss(int x){
        if(x<0) return -x;
        return x;
    }
    int getKey(const Point& p){
        return (abss(p.x)*117+abss(p.y))%mod;
    }
    void init(){
        for(int i=0;i<mod;i++) C[i].clear();
    }
    void add(Point p){
        C[ getKey(p) ].push_back(p);
    }
    int Find(Point p){
        int key = getKey(p);
        for(int i=0; i<C[key].size(); i++)
            if(C[key][i] == p) return C[key][i].id;
        return -1;
    }
};

int n, cnt;
Point P[NMAX];
Point aux[NMAX];
Point shift;
Hash H;
int k;
int dir[NMAX],dir2[NMAX];
bool us[NMAX];
int ans[NMAX];

void dfs(int node){
    if(us[node]) return;
    us[node] = true; cnt++;
    if(dir[node]) dfs(dir[node]);
}

bool Test_Answer(){
    int i;
    memset(dir,0,sizeof(dir));
    memset(dir2,0,sizeof(dir2));
    memset(us,0,sizeof(us));

    for(int i=1; i<=n; i++){
        Point act = aux[i];
        act.Shift(shift);

        int id = H.Find(act);
        if(id!=-1) { dir[ i ] = id ; dir2[ id ] = i ; }
    }

    for(int i=1; i<=n; i++){
        if(us[i]) continue;
        if(dir2[i]!=0) continue;
        cnt = 0;

        dfs(i);
        if( (cnt&1)==1 ) return false;
    }
    for(int i=1; i<=n; i++){
        if(us[i]) continue;
        cnt = 0;

        dfs(i);
        if( (cnt&1)==1 ) return false;
    }
    return true;
}

void dfsAns(int node)
{
    if(us[node]) return;
    us[node] = true; cnt ^= 1;
    ans[node] = cnt+1;
    if(dir[node]) dfsAns(dir[node]);
}

bool Set_Answer()
{
    int i;
    memset(dir,0,sizeof(dir));
    memset(dir2,0,sizeof(dir2));
    memset(us,0,sizeof(us));

    for(int i=1; i<=n; i++){
        Point act = aux[i];
        act.Shift(shift);

        int id = H.Find(act);
        if(id!=-1) { dir[ i ] = id ; dir2[ id ] = i ; }
    }

    for(int i=1; i<=n; i++){
        if(us[i]) continue;
        cnt = 0;

        if(dir2[i]==0)dfsAns(i);
    }
    for(int i=1; i<=n; i++){
        if(us[i]) continue;
        cnt = 0;

        dfsAns(i);
    }
    return true;
}

int main()
{
    freopen("overlap.in","r",stdin);
    freopen("overlap.out","w",stdout);

    scanf("%d",&n); H.init();
    for(int i=1; i<=n; i++)
    {
        P[i].init(i);
        H.add(P[i]);
    }

    for(int k=0; k<4; k++)
    {
        for(int i=1; i<=n; i++)
        {
            aux[i] = P[i];
            aux[i].Rot(k);
        }
        for(int i=2; i<=n; i++)
        {
            shift.x = P[1].x-aux[i].x;
            shift.y = P[1].y-aux[i].y;

            if( Test_Answer() ){
                Set_Answer();
                for(int j=1;j<=n;j++) printf("%d\n",ans[j]);
                return 0;
            }
        }
    }
    return 0;
}