Cod sursa(job #751025)

Utilizator hitman-rebornSawada Tsunayoshi hitman-reborn Data 23 mai 2012 22:11:22
Problema Popandai Scor 8
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.74 kb
#include<stdio.h>
#include<vector>
#include<algorithm>
using namespace std;

#define pb push_back
#define pi pair<int,int>
#define x first
#define y second
#define mp make_pair
#define NMAX 306
#define INF 1000000005

pi v[NMAX];
int tr[5],n,m;
int prep[NMAX][NMAX];
int neg[NMAX],poz[NMAX],nr_neg,nr_poz;
double sol = INF;
vector<int> retin[100 * NMAX];
double Triunghi[2][NMAX];

inline int cmp(const int& a,const int& b)
{
	return v[a].x < v[b].x;
}

inline double Arie(pi a,pi b,pi c)
{
	double arie = 0.5 * (((double)b.y - a.y) * (c.x - a.x) - ((double)c.y - a.y) * (b.x - a.x));
	if(arie < 0)
		return -arie;
	return arie;	
}

inline int RezPrep(int i,int j,int k)
{
	double a = v[i].y - v[j].y;
	double b = v[j].x - v[i].x;
	double c = v[j].y * v[i].x - v[i].y * v[j].x;	
	int val,lim;
	if(a * v[k].x + b * v[k].y + c < 0)
	{
		val = prep[i][j] + prep[j][k] - prep[i][k];
		lim = retin[v[j].x].size();
		if(lim == 2 && retin[v[j].x][1] == v[j].y)	
		{
			double a = v[i].y - v[j].y;
			double b = v[j].x - v[i].x;
			double c = v[j].y * v[i].x - v[i].y * v[j].x;	
			if(a * v[j].x + b * retin[v[j].x][0] + c > 0)
				val--;
		}
	}
	else
	{
		val = prep[i][k] - 1 - prep[i][j] - prep[j][k];
		//if(i == 5 && j == 7 && k == 8)
		//	printf("dadadasda %d\n",val);
		lim = retin[v[j].x].size();
		if(lim == 2 && retin[v[j].x][1] == v[j].y)	
			val++;
	}	
	return val;	
}

inline void AlegePuncte(int indici[],int nr, int ind1, int ind2, int tip)
{
	int i,puncte_sub;
	tr[1] = ind1;
	tr[2] = ind2;
	double arie;
	
	for(i = 1 ; i <= nr; i++)	
	{
		arie = Arie(v[ind1], v[ind2], v[indici[i]]);
		tr[3] = indici[i];
		sort(tr + 1, tr + 4, cmp);
		puncte_sub = RezPrep(tr[1],tr[2],tr[3]);
		//if(ind1 == 5 && ind2 == 7 && indici[i] == 8)
		//	printf("Aria e %lf si %d\n",arie,puncte_sub);
		Triunghi[tip][puncte_sub] = min(Triunghi[tip][puncte_sub], arie);
		tr[1] = ind1;
		tr[2] = ind2;
	}	
	for(i = n - 5; i >= 1; i--)
		Triunghi[tip][i] = min(Triunghi[tip][i], Triunghi[tip][i + 1]);
}
// actualizare sa nu uit

int main ()
{
	int i,j,k;
	double a,b,c;
	
	freopen("popandai.in","r",stdin);
	freopen("popandai.out","w",stdout);
	
	scanf("%d%d",&n,&m);
	
	for(i = 1; i <= n; i++)
	{
		scanf("%d%d",&v[i].x, &v[i].y);
		retin[v[i].x].pb(v[i].y);
	}	
//	printf("PAs 0\n");
	for(i = 1; i <= n; i++)
		sort(retin[v[i].x].begin(),retin[v[i].x].end());
//	printf("Pas 1\n");	
	sort(v + 1, v + n + 1);

	for(i = 1; i <= n; i++)	
		for(j = i + 1; j <= n; j++)
		{
			a = v[i].y - v[j].y;
			b = v[j].x - v[i].x;
			c = v[j].y * v[i].x - v[i].y * v[j].x;
			for(k = 1; k <= n; k++)
				if(k != i && k != j)
				{
					if((v[i].x < v[k].x && v[k].x > v[j].x) || (v[i].x > v[k].x && v[k].x < v[j].x))
						continue;
					//if(i == 1 && j == 4 && k == 2)
					//	printf("%lf %lf %lf\n",a,b,c);
					if(a * v[k].x + b * v[k].y + c < 0)	
					{
						prep[i][j]++;
						prep[j][i]++;
					}	
				}
			//printf("Sub %d %d avem %d\n",i,j,prep[i][j]);	
		}		
	//printf("Pas 2\n");			
		
	for(i = 1; i <= n; i++)	
		for(j = i + 1; j <= n; j++)
			if(i != j)
			{
				for(k = 0; k <= m; k++)
					Triunghi[0][k] = Triunghi[1][k] = INF;
				a = v[i].y - v[j].y;
				b = v[j].x - v[i].x;
				c = v[j].y * v[i].x - v[i].y * v[j].x;
				nr_poz = nr_neg = 0;
				for(k = 1; k <= n; k++)	 
					if(k != i && k != j)
					{
						if(a * v[k].x + b * v[k].y + c < 0)
							neg[++nr_neg] = k;
						else
							poz[++nr_poz] = k;	
					}
				//if(i == 5 && j == 7)
				//	printf("%lf %lf %lf %d %d %d %d\n",a,b,c,nr_neg,nr_poz,neg[nr_neg],poz[nr_poz]);
				AlegePuncte(neg, nr_neg, i, j, 0);	
				AlegePuncte(poz, nr_poz, i, j, 1);
				//if(i == 5 && j == 7)
				//	printf("%lf %lf\n",Triunghi[0][0],Triunghi[1][0]);
				for(k = 0; k <= m; k++)
					sol = min(sol, Triunghi[0][k] + Triunghi[1][m - k]);
			}
	printf("%.1lf\n",sol);		
	
	return 0;
}