Cod sursa(job #342408)

Utilizator CezarMocanCezar Mocan CezarMocan Data 21 august 2009 16:51:20
Problema Popandai Scor 76
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.83 kb
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#define maxn 302

using namespace std;

struct punct {
	int x, y, poz;
};

int sub[maxn][maxn];
int n, K, k, i, j, p1, p2, p3, z;
int sus[maxn], jos[maxn];
punct x[4];
punct v[maxn], ver, t[maxn];
int sol, nr;
int aib[30100];

bool cmp(punct a, punct b) {
	if (a.x < b.x)
		return true;
	return false;
}

inline double tg(punct a, punct b) {
	return 1.0 * (a.y - b.y) / (1.0 * (a.x - b.x));
}

bool cmp2(punct a, punct b) {
	if (tg(a, v[i]) < tg(b, v[i]))
		return true;
	return false;
}

inline int arie(punct a, punct b, punct c) {
	return (a.x * b.y + b.x * c.y + c.x * a.y - c.x * b.y - b.x * a.y - a.x * c.y);
}

inline int det(punct a, punct b, punct c) {
	if (arie(a, b, c) < 0)
		return -1;
	if (arie(a, b, c) > 0)
		return 1;
	return 0;
}

inline int min(int a, int b) {
	if (a < b)
		return a;
	return b;
}

inline int lsb(int x) {
	return (x & (x - 1)) ^ x;
}

inline void update(int poz, int nr) {
	int i;
	for (i = poz; i <= 32000; i += lsb(i))
		aib[i] += nr;
}

inline int query(int poz) {
	int i, q = 0;
	for (i = poz; i > 0; i -= lsb(i))
		q += aib[i];
	return q;
}

int main() {
	freopen("popandai.in", "r", stdin);
	freopen("popandai.out", "w", stdout);
	
	scanf("%d%d", &n, &K);
	for (i = 1; i <= n; i++) {
		scanf("%d%d", &v[i].x, &v[i].y);
		v[i].x++; v[i].y++;
	}
	
	sort(v + 1, v + n + 1, cmp);
	for (i = 1; i <= n; i++)
		v[i].poz = i;
	
	for (i = 1; i <= n; i++) {
		nr = 0;
		for (j = i + 1; j <= n; j++) {
			nr++;
			t[nr] = v[j];
		}
		
		memset(aib, 0, sizeof(aib));
		sort(t + 1, t + nr + 1, cmp2);
		for (j = 1; j <= nr; j++) {
			sub[i][t[j].poz] = sub[t[j].poz][i] = query(t[j].x);
			update(t[j].x, 1);
		}
	}
		
		
	sol = 2000000000;
	for (i = 1; i <= n; i++)
		for (j = i + 1; j <= n; j++) {
			
			for (k = 0; k <= n; k++) 
				sus[k] = jos[k] = 1000000000;
			
			for (k = 1; k <= n; k++) if (k != i && k != j) {
				
				x[1] = v[i]; x[2] = v[j]; x[3] = v[k];	
				sort(x + 1, x + 4, cmp);
				p1 = x[1].poz; p2 = x[2].poz; p3 = x[3].poz;
				ver.x = x[1].x; ver.y = 0;
				int dver = det(x[1], x[3], ver);			
								
				if (det(x[1], x[3], x[2]) == dver) 
					z = sub[p1][p3] - sub[p1][p2] - sub[p2][p3] - 1;
				else
					z = sub[p1][p2] + sub[p2][p3] - sub[p1][p3];		
				
				int a = abs(arie(v[i], v[j], v[k]));
				if (det(v[i], v[j], v[k]) == 1)
					sus[z] = min(sus[z], a);				
				else
					jos[z] = min(jos[z], a);					
			}
			
			for (k = K - 1; k >= 0; k--) {
				sus[k] = min(sus[k], sus[k + 1]);
				jos[k] = min(jos[k], jos[k + 1]);
			}
			
			for (k = 0; k <= K; k++)
				sol = min(sol, sus[k] + jos[K - k]);
		}
		
	if (sol % 2 == 0)
		printf("%d.0", sol / 2);
	else
		printf("%d.5", sol / 2);
	
	return 0;
}