Cod sursa(job #451)

Utilizator m_dersidanDersidan Mihai m_dersidan Data 11 decembrie 2006 12:07:07
Problema Tribute Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.68 kb
# include <stdio.h>
# include <string.h>

# define  maxn  50002

# define  _fin  "tribute.in"
# define  _fout "tribute.out"


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;
}