Cod sursa(job #125905)

Utilizator raula_sanChis Raoul raula_san Data 20 ianuarie 2008 21:02:27
Problema Inundatii Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.45 kb
#include <cstdio>
#include <queue>

#define dim 50001

using namespace std;

int X[dim];
int Y[dim];
int Z[dim];
int L[dim];

int N;

long long Sol;

priority_queue <int> Q;

void clear()
{
	while(Q.empty() == false)
		Q.pop();
}

void solve(int A[])
{
	int i, x, neg = 0, pos;
	
	long long ret = 0;
	
	for(i=0; i<N; ++i)
	{
		L[i+1] = i - A[i+1];
		
		if(L[i+1] < 0)
		{
			++ neg;
			Q.push(L[i+1]);
		}
		
		ret += L[i+1] < 0 ? -L[i+1] : L[i+1];
	}
	
	pos = N - neg;
	
	while(Q.empty() == false)
	{
		if(neg > pos)
		{
			x = Q.top(); Q.pop();
			
			ret -= -x * neg;
			ret += -x * pos;
			
			-- neg;
			++ pos;
		}
		else
		{
			clear();
			break;
		}	
	}
	
	Sol += ret;
}

void kkt(int A[])
{
	int i, ret, min = 0;
	
	for(i=0; i<N; ++i)
		L[i+1] = i;
	
	for(i=1; i<=N; ++i)
		min += L[i] > A[i] ? L[i] - A[i] : A[i] - L[i];
	
	for(;;)
	{
		for(i=1; i<=N; ++i)
			++ L[i];
			
		ret = 0;
		
		for(i=1; i<=N; ++i)
			ret += L[i] > A[i] ? L[i] - A[i] : A[i] - L[i];
			
		if(ret < min)
			min = ret;
			
		else
			break;
	}
	
	Sol += min;
}

int main()
{
	freopen("inundatii.in", "rt", stdin);
	freopen("inundatii.out", "wt", stdout);
	
	int i;
	
	for(scanf("%d", &N), i=1; i<=N; ++i)
		scanf("%d %d %d", X+i, Y+i, Z+i);
/*	
	solve(X);
	solve(Y);
	solve(Z);
*/

	kkt(X);
	kkt(Y);
	kkt(Z);
	
	printf("%lld", Sol);
	
	fclose(stdin);
	fclose(stdout);
	return 0;
}