Artifact Content
Not logged in

Artifact 0a15ef1d15a672eef9709ff0b901fb25d98163f2


#include <iostream>
#include <sstream>
#include <iomanip>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <algorithm>
#include <numeric>
#include <iterator>
#include <functional>
#include <complex>
#include <queue>
#include <stack>
#include <cmath>
#include <cassert>
#include <cstring>
using namespace std;
typedef long long LL;
typedef complex<double> CMP;

double outer_prod(const CMP& a, const CMP& b) { return imag(conj(a)*b); }
double inner_prod(const CMP& a, const CMP& b) { return real(conj(a)*b); }

int ccw(const CMP& a, CMP b, CMP c) {
	b -= a; c -= a;
	if( outer_prod(b,c) > 0 ) return +1; // counter clockwise
	if( outer_prod(b,c) < 0 ) return -1; // clockwise
	if( inner_prod(b,c) < 0 ) return +2; // c--a--b on line
	if( norm(b) < norm(c) )   return -2; // a--b--c on line
	return 0;
}

bool byX( const CMP& a, const CMP& b ) {
	if( a.real() != b.real() )
		return a.real() < b.real();
	return a.imag() < b.imag();
}

vector<CMP> convex_hull( vector<CMP> p )
{
	#define IS_RIGHT <0   // skip on-line verts
	//#define IS_RIGHT ==-1 // take all

	sort(p.begin(), p.end(), &byX);

	vector<CMP> ans;
	for(int i=0; i<p.size(); ans.push_back(p[i++])) // left-to-right
		while( ans.size()>=2 && ccw(ans[ans.size()-2], ans[ans.size()-1], p[i]) IS_RIGHT )
			ans.pop_back();
	if( ans.size() == p.size() )
		return ans;
	for(int i=p.size()-2; i>=0; ans.push_back(p[i--])) // right-to-left
		while( ans.size()>=2 && ccw(ans[ans.size()-2], ans[ans.size()-1], p[i]) IS_RIGHT )
			ans.pop_back();
	ans.pop_back();
	return ans;
}

double area( const vector<CMP>& q )
{
	double a = 0.0;

	CMP o = q[0];
	for(int i=1; i+1<q.size(); ++i)
		a += outer_prod(q[i]-o, q[i+1]-o);
	return abs(a)/2;
}

class BatmanAndRobin { public:
	double minArea(vector <int> x, vector <int> y) 
	{
		int N = x.size();
		vector<CMP> p;
		for(int i=0; i<N; ++i)
			p.push_back(CMP(x[i],y[i]));

		const double eps = 1e-6;
		CMP diff[] = {CMP(eps,0), CMP(0,eps), CMP(-eps,0), CMP(0,-eps)};
		double answer = area(convex_hull(p));
		for(int i=0; i<N; ++i)
			for(int j=i+1; j<N; ++j) {
				for(int di=0; di<4; ++di)
					for(int dj=0; dj<4; ++dj) {
						vector<CMP> a = left_of(p, p[i]+diff[di], p[j]+diff[dj]);
						vector<CMP> b = right_of(p, p[i]+diff[di], p[j]+diff[dj]);
						double aa = a.size()<=2 ? 0 : area(convex_hull(a));
						double bb = b.size()<=2 ? 0 : area(convex_hull(b));
						answer = min(answer, max(aa,bb));
					}
			}
		return answer;
	}

	vector<CMP> left_of(const vector<CMP>& p, const CMP& o, CMP v)
	{
		v -= o;
		vector<CMP> r;
		for(int i=0; i<p.size(); ++i)
			if( is_left(p[i]-o, v) )
				r.push_back(p[i]);
		return r;
	}
	vector<CMP> right_of(const vector<CMP>& p, const CMP& o, CMP v)
	{
		v -= o;
		vector<CMP> r;
		for(int i=0; i<p.size(); ++i)
			if( !is_left(p[i]-o, v) )
				r.push_back(p[i]);
		return r;
	}
	bool is_left(const CMP& p, const CMP& v)
	{
		return arg(p/v)>0;
	}
};

// BEGIN CUT HERE
#include <ctime>
double start_time; string timer()
 { ostringstream os; os << " (" << int((clock()-start_time)/CLOCKS_PER_SEC*1000) << " msec)"; return os.str(); }
template<typename T> ostream& operator<<(ostream& os, const vector<T>& v)
 { os << "{ ";
   for(typename vector<T>::const_iterator it=v.begin(); it!=v.end(); ++it)
   os << '\"' << *it << '\"' << (it+1==v.end() ? "" : ", "); os << " }"; return os; }
void verify_case(const double& Expected, const double& Received) {
 bool ok = (abs(Expected - Received) < 1e-9);
 if(ok) cerr << "PASSED" << timer() << endl;  else { cerr << "FAILED" << timer() << endl;
 cerr << "\to: \"" << Expected << '\"' << endl << "\tx: \"" << Received << '\"' << endl; } }
#define CASE(N) {cerr << "Test Case #" << N << "..." << flush; start_time=clock();
#define END	 verify_case(_, BatmanAndRobin().minArea(x, y));}
int main(){

CASE(0)
	int x_[] = {100,100,90,90,-100,-100,-90,-90};
	  vector <int> x(x_, x_+sizeof(x_)/sizeof(*x_)); 
	int y_[] = {100,90,100,90,-100,-90,-100,-90};
	  vector <int> y(y_, y_+sizeof(y_)/sizeof(*y_)); 
	double _ = 100.0; 
END
CASE(1)
	int x_[] = {-1000,-1000,1000,1000,1000,-1000};
	  vector <int> x(x_, x_+sizeof(x_)/sizeof(*x_)); 
	int y_[] = {-1000,1000,-1000,1000,0,0};
	  vector <int> y(y_, y_+sizeof(y_)/sizeof(*y_)); 
	double _ = 0.0; 
END
CASE(2)
	int x_[] = {-1000,-1000,1000,1000,0};
	  vector <int> x(x_, x_+sizeof(x_)/sizeof(*x_)); 
	int y_[] = {-1000,1000,-1000,1000,0};
	  vector <int> y(y_, y_+sizeof(y_)/sizeof(*y_)); 
	double _ = 1000000.0; 
END
CASE(3)
	int x_[] = {-904,-812,-763,-735,-692,-614,-602,-563,-435,-243,-87,-52,-28,121,126,149,157,185,315,336,390,470,528,591,673,798,815,837,853,874};
	  vector <int> x(x_, x_+sizeof(x_)/sizeof(*x_)); 
	int y_[] = {786,10,-144,949,37,-857,-446,-969,-861,-712,5,-972,-3,-202,-845,559,-244,-542,-421,422,526,-501,-791,-899,-315,281,-275,467,743,-321};
	  vector <int> y(y_, y_+sizeof(y_)/sizeof(*y_)); 
	double _ = 1067472.0; 
END
CASE(4)
	int x_[] = {-904,-812,-763,-735,-692,-614,-602,-563,-435,-243,-87,-52,-28,121,126,149,157,185,315,336,390,470,528,591,673,798,815,837,853,874,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
	  vector <int> x(x_, x_+sizeof(x_)/sizeof(*x_)); 
	int y_[] = {786,10,-144,949,37,-857,-446,-969,-861,-712,5,-972,-3,-202,-845,559,-244,-542,-421,422,526,-501,-791,-899,-315,281,-275,467,743,-321,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
	  vector <int> y(y_, y_+sizeof(y_)/sizeof(*y_)); 
	double _ = -1; 
END
/*
CASE(5)
	int x_[] = ;
	  vector <int> x(x_, x_+sizeof(x_)/sizeof(*x_)); 
	int y_[] = ;
	  vector <int> y(y_, y_+sizeof(y_)/sizeof(*y_)); 
	double _ = ; 
END
*/
}
// END CUT HERE