Cod sursa(job #752713)

Utilizator mihaipopa12Popa Mihai mihaipopa12 Data 29 mai 2012 11:19:57
Problema Popandai Scor 72
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.19 kb
#include<stdio.h>
#include<algorithm>

#define maxn 305

using namespace std;

FILE*f=fopen("popandai.in","r");
FILE*g=fopen("popandai.out","w");

const int INF = (1LL<<31)-1;
int n,K;
int sub[maxn][maxn],up[maxn],down[maxn];

struct pct{
	int x,y;
}A[maxn];

struct cmp{
	inline bool operator () ( const pct &a , const pct &b ){
		if ( a.x != b.x )
			return a.x < b.x;
		return a.y < b.y;
	}
};

inline int det ( const int &X1 , const int &Y1 , const int &X2 , const int &Y2 , const int &X3 , const int &Y3 ){
	int d = (X1-X3)*(Y2-Y3) - (X2-X3)*(Y1-Y3);
	return d;
}

inline int inside ( const int &i , const int &j , const int &k ){
	
	int d = det(A[i].x,A[i].y,A[j].x,A[j].y,A[k].x,A[k].y);
	if ( d < 0 ){
		return sub[i][j]+sub[j][k]-sub[i][k];
	}
	else{
		return sub[i][k]-sub[i][j]-sub[j][k]-1;
	}
}

int main () {
	
	fscanf(f,"%d %d",&n,&K);
	for ( int i = 1 ; i <= n ; ++i ){
		fscanf(f,"%d %d",&A[i].x,&A[i].y);
	}
	
	sort(A+1,A+n+1,cmp());
	
	for ( int i = 1 ; i < n ; ++i ){
		for ( int j = i + 1 ; j <= n ; ++j ){
			
			for ( int k = i + 1 ; k < j ; ++k ){
				if ( A[i].x < A[k].x && A[k].x <= A[j].x && det(A[i].x,A[i].y,A[j].x,A[j].y,A[k].x,A[k].y) < 0 ){
					++sub[i][j];
				}
			}
		}
	}
	
	int sol = INF;
	for ( int i = 1 ; i < n ; ++i ){
		for ( int j = i + 1 ; j <= n ; ++j ){
			
			up[0] = down[0] = INF;
			for ( int k = 1 ; k <= n ; ++k ){
				up[k] = down[k] = INF;
				if ( i == k || j == k )	continue ;
				
				int in;
				if ( i > k ){
					in = inside(k,i,j);
				}
				else{
					if ( j > k ){
						in = inside(i,k,j);
					}
					else{
						in = inside(i,j,k);
					}
				}
				
				int d = det(A[i].x,A[i].y,A[j].x,A[j].y,A[k].x,A[k].y);
				if ( d > 0 ){
					up[in] = min(up[in],d);
				}
				else{
					down[in] = min(down[in],-d);
				}
			}
			
			for ( int k = n - 1 ; k >= 0 ; --k ){
				up[k] = min(up[k],up[k+1]);
				down[k] = min(down[k],down[k+1]);
			}
			
			for ( int k = 0 ; k <= K ; ++k ){
				if ( up[k] == INF || down[K-k] == INF )	continue ;
				sol = min(sol,up[k]+down[K-k]);
			}
		}
	}
	
	fprintf(g,"%.1lf\n",(double)sol/2);
	
	fclose(f);
	fclose(g);
	
	return 0;
}