Cod sursa(job #125551)

Utilizator ProstuStefan-Alexandru Filip Prostu Data 20 ianuarie 2008 14:39:32
Problema Inundatii Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.45 kb
#include <cstdio>
#include <algorithm>

using namespace std;

typedef long long llong;
typedef pair <llong, int> PLI;

#define x first
#define y second

const int NMAX = 1 << 16;
const int INF = 0x3f3f3f3f;
const int MIN = -NMAX, MAX = INF;

int N;
int A[NMAX], B[NMAX], C[NMAX];

void read(void) {
	FILE *fin = fopen("inundatii.in", "rt");
	int i;

	fscanf(fin, " %d", &N);

	for (i = 1; i <= N; ++i)
		fscanf(fin, " %d %d %d", A+i, B+i, C+i);

	fclose(fin);
}

llong get(int A[], int p, int h) {
	int i;
	llong rez = 0;

	for (i = p; i <= N; ++i)
		rez += abs(h+i-p - A[i]);

	return rez;
}

int seek(int A[], int p, int l, int h) {
//	printf("l=%d h=%d\n", l, h);
	if (l == h) return l;
	if (h - l <= 4) {
		int i, poz = l, t, aux;
		t = get(A, p, l);
		for (i = l+1; i <= h; ++i)
			if ((aux = get(A, p, i)) < t)
				t = aux, poz = i;
		return poz;
	}

	int l3, h3;
	l3 = ((llong)l * 2 + h) / 3;
	h3 = ((llong)l + 2 * h) / 3;
	if (get(A, p, l3) > get(A, p, h3))
		return seek(A, p, l3, h);
	else
		return seek(A, p, l, h3);
}

llong solve(int A[]) {
	int i, lh, h;
	llong rez = 0;

	lh = MIN;
	for (i = 1; i <= N; ++i) {
		h = seek(A, i, lh, INF);
//		printf("%d\n", h);
		rez += abs(h - A[i]);
		lh = h + 1;
	}

//	printf("rez=%lld\n", rez);
	return rez;
}

void write(void) {
	FILE *fout = fopen("inundatii.out", "wt");

	llong rez;
	
	rez = solve(A) + solve(B) + solve(C);

	fprintf(fout, "%lld\n", rez);

	fclose(fout);
}

int main(void) {

	read();

	write();

	return 0;
}