Cod sursa(job #64514)

Utilizator gcosminGheorghe Cosmin gcosmin Data 3 iunie 2007 19:48:06
Problema Popandai Scor 88
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.9 kb
#include <stdio.h>
#include <vector>
using namespace std;

#define NMAX 310
#define INF 1000000000
#define ff first
#define ss second
#define MP make_pair

int N, K;

pair <int, int> a[NMAX];

int nr[NMAX][NMAX];

int best[NMAX];

inline int semn(pair <int, int> a, pair <int, int> b, pair <int, int> c)
{
	int q = a.ff * (b.ss - c.ss) - a.ss * (b.ff - c.ff) + b.ff * c.ss - b.ss * c.ff;
	if (q < 0) return -1;
	if (q > 0) return 1;
	return 0;
}

inline int MIN(int a, int b) { return (a < b) ? a : b; }
inline int MAX(int a, int b) { return (a > b) ? a : b; }
inline int ABS(int x) { return (x < 0) ? -x : x; }

inline int arie(pair<int, int> a, pair<int, int> b, pair <int, int> c) 
{ 
	return ABS(a.ff * (b.ss - c.ss) - a.ss * (b.ff - c.ff) + b.ff * c.ss - b.ss * c.ff); 
}

inline int nr_in(int x, int y, int z)
{
	int e = 0, rez = -1;

	if (a[x].ff == a[y].ff) rez = nr[z][x] - nr[z][y], e = 1;
	else
	if (a[x].ff == a[z].ff) rez = nr[y][x] - nr[y][z], e = 1;
	else
	if (a[y].ff == a[z].ff) rez = nr[x][y] - nr[x][z], e = 1;

	if (e) {
//		printf("da %d\n", rez);
		if (rez > 0) rez--;
		else 
		if (rez < 0) rez++;
		return ABS(rez);
	}

	if (MIN(a[y].ff, a[z].ff) < a[x].ff && a[x].ff < MAX(a[y].ff, a[z].ff)) rez = nr[y][z] - nr[x][y] - nr[x][z] + nr[x][x];
	else
	if (MIN(a[x].ff, a[z].ff) < a[y].ff && a[y].ff < MAX(a[x].ff, a[z].ff)) rez = nr[x][z] - nr[y][x] - nr[y][z] + nr[y][y];
	else
	if (MIN(a[x].ff, a[y].ff) < a[z].ff && a[z].ff < MAX(a[x].ff, a[y].ff)) rez = nr[x][y] - nr[z][x] - nr[z][y] + nr[z][z];

	if (rez > 0) rez--;
	return ABS(rez);
}

int main()
{
	int i, j, q, smn, k;

	freopen("popandai.in", "r", stdin);
	freopen("popandai.out", "w", stdout);

	scanf("%d %d", &N, &K);

	for (i = 1; i <= N; i++) scanf("%d %d", &a[i].first, &a[i].second);

	// calculez smecheria
	
	for (i = 1; i <= N; i++)
		for (j = i + 1; j <= N; j++) {
			if (a[i].ff == a[j].ff) continue;

			smn = semn(MP(a[i].ff, a[i].ss - 1), a[i], a[j]);

			for (k = 1; k <= N; k++) {
				q = semn(a[k], a[i], a[j]);
				if (q != smn) continue;

				if (MIN(a[i].ff, a[j].ff) <= a[k].ff && a[k].ff <= MAX(a[i].ff, a[j].ff)) nr[i][j]++, nr[j][i]++;
			}
		}

	for (i = 1; i <= N; i++)
		for (j = 1; j <= N; j++)
			nr[i][i] += a[i].ff == a[j].ff && a[j].ss < a[i].ss;

//	printf("%d\n", nr_in(6, 5, 8));

	int rez = INF;

	for (i = 1; i <= N; i++)
		for (j = i + 1; j <= N; j++) {
			for (k = 0; k <= N; k++) best[k] = INF;

			for (k = 1; k <= N; k++) {
				if (k == i || k == j) continue;
				if (semn(a[k], a[i], a[j]) < 0) continue;
				q = nr_in(i, j, k);
				best[q] = MIN(best[q], arie(a[i], a[j], a[k]));
			}

			for (k = N - 1; k >= 0; k--) best[k] = MIN(best[k], best[k  + 1]);

			for (k = 1; k <= N; k++) {
				if (k == i || k == j) continue;
				if (semn(a[k], a[i], a[j]) > 0) continue;
				q = nr_in(i, j, k);
				rez = MIN(rez, arie(a[i], a[j], a[k]) + best[MAX(K - q, 0)]);
			}
		}

	printf("%0.1lf\n", rez * 0.5);

fclose(stdin);
fclose(stdout);
return 0;
}