Cod sursa(job #1193703)

Utilizator silvatheviprersilviu catioiu silvatheviprer Data 1 iunie 2014 15:37:21
Problema Tribute Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.96 kb
#include <stdio.h>
# include <string.h>
#define  maxn  50002
# define  _fin  "tribute.in"
# define  _fout "tribute.out"
using namespace std;
typedef struct punct
{
    int x, y;
}   punct;

int n, dx, dy, sol;

punct p[maxn], sx[maxn], sy[maxn];


void readf()
{
    FILE *fin = fopen(_fin, "r");

    int i;

    for (fscanf(fin, "%d %d %d", &n, &dx, &dy), i=1; i<=n; i++)
         fscanf(fin, "%d %d", &p[i].x, &p[i].y);

    fclose(fin);
}

void radix()
{
    int *vx[maxn], *vy[maxn], nx[maxn], ny[maxn], i, j, ax, ay;

    memset(nx, 0, sizeof(nx)), memset(ny, 0, sizeof(ny));

    for (i=1; i<=n; i++)
        ++nx[ p[i].x ], ++ny[ p[i].y ];
    // alocam spatiul necesar -> maxim 2*maxn
    for (i=0; i<maxn; i++)   // n = maxc
        vx[i] = new int[ nx[i]+1 ], vx[i][0] = 0,
        vy[i] = new int[ ny[i]+1 ], vy[i][0] = 0;
    // ne creem vectorii
    for (i=1; i<=n; i++)
        vx[ p[i].x ][ ++vx[ p[i].x ][ 0 ] ] = i,    // care punct
        vy[ p[i].y ][ ++vy[ p[i].y ][ 0 ] ] = i;

    for (ax=ay=0, i=0; i<maxn; i++)
    {
        // adaugam puncte in sx
        for (j=1; j<=vx[i][0]; j++)
            sx[ ++ax ] = p[ vx[i][j] ];
        for (j=1; j<=vy[i][0]; j++)
            sy[ ++ay ] = p[ vy[i][j] ];
    }

    // acum, sx retine punctele sortate dupa x, iar sy, sortate dupa y
}

void solve()
{
    int i, to, left, right, act, minx, miny;    // i -> coordonata din dreapta a
    int dl, dr;
    radix();

    // baleierea pe x -> avem un vector cu dimensiunea dx, capatul dreapta il mutam de la primul varf pana la ultimul+dx
    // calculez prima data distanta pentru capatul dreapta = cel mai din stanga punt
    for (act=0, i=1; i<=n; act += sx[i].x - sx[1].x, ++i);
    // acum baleiez vectorul
    for (right=1; sx[right].x == sx[1].x; ++right);
    for (left=0,i=sx[1].x+1, minx = act; i<=sx[n].x; i++)
    {
        // mut right daca este cazul
        for (dl=0; sx[left+1].x < i-dx; ++act, ++left , ++dl);
        // mut left  daca este cazul
        for (dr=0; sx[right].x == i   ; --act, ++right, ++dr);
        // si modific distanta pentru punctele ramase
        act = act + (left-dl) - (n+1-right);

        act<minx?minx=act:0;
    }

    for (act=0, i=1; i<=n; act += sy[i].y - sy[1].y, ++i);
    // acum baleiez vectorul
    for (right=1; sy[right].y == sy[1].y; ++right);
    for (left=0,i=sy[1].y+1, miny = act; i<=sy[n].y; i++)
    {
        // mut right daca este cazul
        for (dl=0; sy[left+1].y < i-dy; ++act, ++left , ++dl);
        // mut left  daca este cazul
        for (dr=0; sy[right].y == i   ; --act, ++right, ++dr);
        // si modific distanta pentru punctele ramase
        act = act + (left-dl) - (n+1-right);

        act<miny?miny=act:0;
    }

    sol = minx + miny;
}

void writef()
{
    FILE *fout = fopen(_fout, "w");
    fprintf(fout, "%d\n", sol), fclose(fout);
}

int main()
{
    readf();
    solve();
    writef();

    return 0;
}