Cod sursa(job #125151)

Utilizator MariusMarius Stroe Marius Data 20 ianuarie 2008 11:42:52
Problema Inundatii Scor 100
Compilator cpp Status done
Runda preONI 2008, Runda 3, Clasele 11-12 Marime 1.36 kb
#include <cstdio>
using namespace std;

const char iname[] = "inundatii.in";
const char oname[] = "inundatii.out";

#define MAXN  50005

int X[MAXN], Y[MAXN], Z[MAXN];

typedef long long i64;


i64 f(int X[], int n, int coord)
{
	i64 sum, cnt, tsum;

	sum = cnt = tsum = 0;
	for (int i = n; coord > X[i]; -- i)
		sum += (i64)(coord - X[i]), cnt ++;
	tsum += sum + ((cnt + 1) * cnt) / 2;
	sum = cnt = 0;
	for (int i = 1; X[i] > coord; ++ i)
		sum += (i64)(X[i] - coord), cnt ++;
	tsum += sum + ((cnt + 1) * cnt) / 2;

	return tsum;
}

i64 search(int X[], int n, int left, int right)
{
	if (right - left <= 2) {
		i64 one = f(X, n, left);
		i64 two = f(X, n, right);
		i64 three = f(X, n, left + 1);
		if (one > two)  one = two;
		if (one > three)  one = three;
		return one;
	}
	int leftThird  = (left * 2 + right) / 3;
	int rightThird = (left + right * 2) / 3;
	if (f(X, n, leftThird) > f(X, n, rightThird))
		return search(X, n, leftThird, right);
	else
		return search(X, n, left, rightThird);
}

i64 solve(int X[], int n) {
    return search(X, n, X[n], X[1]);	
}

int main(void)
{
	freopen(iname, "r", stdin);
	freopen(oname, "w", stdout);
	
	int n;
	
	scanf("%d\n", &n);
	for (int i = 1; i <= n; ++ i)
		scanf("%d %d %d\n", &X[i], &Y[i], &Z[i]);
	printf("%lld\n", solve(X, n) + solve(Y, n) + solve(Z, n));

	return 0;
}