Problem:
Problem C:
Fishnet
A fisherman named Etadokah awoke in a very small island. He could see calm, beautiful and blue sea around the island. The previous night he had encountered a terrible storm and had reached this uninhabited island. Some wrecks of his ship were spread around him. He found a square wood-frame and a long thread among the wrecks. He had to survive in this island until someone came and saved him.
In order to catch fish, he began to make a kind of fishnet by cutting the long thread into short threads and fixing them at pegs on the square wood-frame (Figure 1). He wanted to know the sizes of the meshes of the fishnet to see whether he could catch small fish as well as large ones.
The wood-frame is perfectly square with four thin edges one meter long.. a bottom edge, a top edge, a left edge, and a right edge. There are
n
pegs on each edge, and thus there are 4
n
pegs in total. The positions ofpegs are represented by their (
x
,
y
)-coordinates. Those of an example case with
n
= 2 are depicted in Figures 2 and 3. The position of the
i
th peg on the bottom edge is represented by (
a
i
, 0) . That on the top edge, on the left edge and on the right edge are represented by (
b
i
, 1) , (0,
c
i
), and (1,
d
i
), respectively. The long thread is cut into 2
n
threads with appropriate lengths. The threads are strained between (
a
i
, 0) and (
b
i
, 1) , and between (0,
c
i
) and (1,
d
i
) (
i
= 1,...,
n
) .
You should write a program that reports the size of the largest mesh among the (
n
+ 1)
2
meshes of the fishnet made by fixing the threads at the pegs. You may assume that the thread he found is long enough to make the fishnet and that the wood-frame is thin enough for neglecting its thickness.
Figure 1. A wood-frame with 8 pegs.
Figure 2. Positions of pegs (indicated by small black circles)
Figure 3. A fishnet and the largest mesh (shaded)
Input
The input consists of multiple subproblems followed by a line containing a zero that indicates the end of input. Each subproblem is given in the following format.
n
a
1
a
2
...
a
n
b
1
b
2
...
b
n
c
1
c
2
...
c
n
d
1
d
2
...
d
n
An integer
n
followed by a newline is the number of pegs on each edge.
a
1
,...,
a
n
,
b
1
,...,
b
n
,
c
1
,...,
c
n
,
d
1
,...,
d
n
are decimal fractions, and they are separated by a space character except that
a
n
,
b
n
,
c
n
and
d
n
are followed by a new line. Each
a
i
(
i
= 1,...,
n
) indicates the
x
-coordinate of the
i
th peg on the bottom edge. Each
b
i
(
i
= 1,...,
n
) indicates the
x
-coordinate of the
i
th peg on the top edge. Each
c
i
(
i
= 1,...,
n
) indicates the
y
-coordinate of the
i
th peg on the left edge. Each
d
i
(
i
= 1,...,
n
) indicates the
y
-coordinate of the
i
th peg on the right edge. The decimal fractions are represented by 7 digits after the decimal point. In addition you may assume that 0 <
n
≤ 30 , 0 <
a
1
<
a
2
< ... <
a
n
< 1, 0 <
b
1
<
b
2
< ... <
b
n
< 1 , 0 <
c
1
<
c
2
< ... <
c
n
< 1 and 0 <
d
1
≤
d
2
< ... <
d
n
< 1 .
Output
For each subpr
...(truncated)

Submitted solutions:

code_snippet: #include <iostream>
#include <iomanip>
#include <complex>
#include <vector>
#include <algorithm>
#include <cmath>
#include <array>
using namespace std;
const double EPS = 1e-10;
const double INF = 1e12;
#define EQ(n,m) (abs((n)-(m)) < EPS)
#define X real()
#define Y imag()

typedef complex<double> P;
typedef vector<P> VP;
struct L : array<P, 2>{
    L(const P& a, const P& b){ at(0)=a; at(1)=b; }
    L(){}
};

namespace std{
    bool operator < (const P& a, const P& b){
        return !EQ(a.X,b.X) ? a.X<b.X : a.Y+EPS<b.Y;
    }
    bool operator == (const P& a, const P& b){
        return abs(a-b) < EPS;
    }
}

double dot(P a, P b){
    return (conj(a)*b).X;
}
double cross(P a, P b){
    return (conj(a)*b).Y;
}
int ccw(P a, P b, P c){
    b -= a;
    c -= a;
    if(cross(b,c) > EPS) return +1; //ccw
    if(cross(b,c) < -EPS) return -1; //cw
    if(dot(b,c) < -EPS) return +2; //c-a-b
    if(abs(c)-abs(b) > EPS) return -2; //a-b-c
    return 0; //a-c-b
}

P crosspointLL(const L &l, const L &m) {
  double A = cross(l[1]-l[0], m[1]-m[0]);
  double B = cross(l[1]-l[0], l[1]-m[0]);
  return m[0] + B/A *(m[1]-m[0]);
}
double getarea(const VP &poly){
    double ret = 0;
    for (int i=0; i<(int)poly.size(); i++){ 
        ret += cross(poly[i], poly[(i+1)%poly.size()]);
    }
    return ret*0.5;
}
VP convex_cut(const VP& p, const L& l){
    VP ret;
    int n = p.size();
    for(int i=0; i<n; i++){
        P curr = p[i];
        P next = p[(i+1)%n];
        if(ccw(l[0], l[1], curr) != -1) ret.push_back(curr);
        if(ccw(l[0], l[1], curr) *ccw(l[0], l[1], next) == -1){
            ret.push_back(crosspointLL(L(curr, next), l));
        }
    }
    return ret;
}


int main(){
    while(1){
        int n;
        cin >> n;
        if(n==0) break;

        double in;
        VP a(n+2),b(n+2),c(n+2),d(n+2);
        for(int i=1; i<=n; i++){ cin >> in; a[i] = P(in, 0); }
        for(int i=1; i<=n; i++){ cin >> in; b[i] = P(in, 1); }
        for(int i=1; i<=n; i++){ cin >> in; c[i] = P(0, in); }
        for(int i=1; i<=n; i++){ cin >> in; d[i] = P(1, in); }
        VP sq{P(0,0),P(1,0),P(1,1),P(0,1)};
        a[0] = c[0] = sq[0];
        a[n+1] = d[0] = sq[1];
        b[n+1] = d[n+1] = sq[2];
        b[0] = c[n+1] = sq[3];

        double ans = 0;
        for(int i=0; i<n+1; i++){
            for(int j=0; j<n+1; j++){
                L cut[4] = {L(b[i], a[i]), L(a[i+1], b[i+1]), L(c[j], d[j]), L(d[j+1], c[j+1])};
                VP poly = sq;
                for(int t=0; t<4; t++){
                    poly = convex_cut(poly, cut[t]);
                }
                ans = max(ans, getarea(poly));
            }
        }
        cout << fixed << setprecision(6);
        cout << ans << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3296
final_rank: 5

code_snippet: #include "bits/stdc++.h"
#include<unordered_map>
#include<unordered_set>
#pragma warning(disable:4996)
using namespace std;
using ld = long double;
const ld eps = 1e-9;


/* 幾何の基本 */

#include <complex>

typedef complex<ld> Point;


const ld pi = acos(-1.0);
const ld dtop = pi / 180.;
const ld ptod = 1. / dtop;

namespace std {
	bool operator<(const Point &lhs, const Point &rhs) {
		if (lhs.real() < rhs.real() - eps) return true;
		if (lhs.real() > rhs.real() + eps) return false;
		return lhs.imag() < rhs.imag();
	}
}

// 点の入力
Point input_Point() {
	ld x, y;
	cin >> x >> y;
	return Point(x, y);
}

// 誤差つき等号判定
bool eq(const ld a, const ld b) {
	return (abs(a - b) < eps);
}

// 内積
ld dot(const Point& a, const Point& b) {
	return real(conj(a) * b);
}

// 外積
ld cross(const Point& a, const Point& b) {
	return imag(conj(a) * b);
}

// 直線の定義
class Line {
public:
	Point a, b;
	Line() : a(Point(0, 0)), b(Point(0, 0)) {}
	Line(Point a, Point b) : a(a), b(b) {}
	Point operator[](const int _num)const {
		if (_num == 0)return a;
		else if (_num == 1)return b;
		else {
			assert(false);
			return Point();
		}
	}
};

// 円の定義
class Circle {
public:
	Point p;
	ld r;
	Circle() : p(Point(0, 0)), r(0) {}
	Circle(Point p, ld r) : p(p), r(r) {}
};

// ccw
// 1: a,b,cが反時計周りの順に並ぶ
//-1: a,b,cが時計周りの順に並ぶ
// 2: c,a,bの順に直線に並ぶ
//-2: a,b,cの順に直線に並ぶ
// 0: a,c,bの順に直線に並ぶ
int ccw(const Point& a, const Point &b, const Point &c) {
	const Point nb(b - a);
	const Point nc(c - a);
	if (cross(nb, nc) > eps) return 1;   // a,b,cが反時計周りの順に並ぶ
	if (cross(nb, nc) < -eps) return -1; // a,b,cが時計周りの順に並ぶ
	if (dot(nb, nc) < 0) return 2;       // c,a,bの順に直線に並ぶ
	if (norm(nb) < norm(nc)) return -2;  // a,b,cの順に直線に並ぶ
	return 0;                          // a,c,bの順に直線に並ぶ
}


/* 交差判定 */

// 直線と直線の交差判定
bool isis_ll(const Line& l, const Line& m) {
	return !eq(cross(l.b - l.a, m.b - m.a), 0);
}

// 直線と線分の交差判定
bool isis_ls(const Line& l, const Line& s) {
	return isis_ll(l, s) &&
		(cross(l.b - l.a, s.a - l.a) * cross(l.b - l.a, s.b - l.a) < eps);
}

// 線分と線分の交差判定
bool isis_ss(const Line& s, const Line& t) {
	return ccw(s.a, s.b, t.a) * ccw(s.a, s.b, t.b) <= 0 &&
		ccw(t.a, t.b, s.a) * ccw(t.a, t.b, s.b) <= 0;
}

// 点の直線上判定
bool isis_lp(const Line& l, const Point& p) {
	return (abs(cross(l.b - p, l.a - p)) < eps);
}

// 点の線分上判定
bool isis_sp(const Line& s, const Point& p) {
	return (abs(s.a - p) + abs(s.b - p) - abs(s.b - s.a) < eps);
}

// 垂線の足
Point proj(const Line &l, const Point& p) {
	ld t = dot(p - l.a, l.b - l.a) / norm(l.a - l.b);
	return l.a + t * (l.b - l.a);
}

//線対象の位置にある点
Point reflect(const Line &l, const Point &p) {
	Point pr = proj(l, p);
	return pr * 2.l - p;
}

// 直線と直線の交点
Point is_ll(const Line &s, const Line& t) {
	Point sv = s.b - s.a, tv = t.b - t.a;
	assert(cross(sv, tv) != 0);
	return s.a + sv * cross(tv, t.a - s.a) / cross(tv, sv);
}
// 直線と直線の交点
vector<Point> is_ll2(const Line &s, const Line& t) {
	Point sv = s.b - s.a, tv = t.b - t.a;
	if (cross(sv, tv) != 0)return vector<Point>(1, is_ll(s, t));
	else {
		vector<Point>ans;
		for (int k = 0; k < 2; ++k) {
			if (isis_sp(s, t[k]) && find(ans.begin(), ans.end(), t[k]) == ans.end())ans.push_back(t[k]);
			if (isis_sp(t, s[k]) && find(ans.begin(), ans.end(), s[k]) == ans.end())ans.push_back(s[k]);
		}
		return ans;
	}
}
// 線分と線分の交点
//　重なってる部分あるとassert(false)
Point is_ss(const Line &s, const Line& t) {
	if (isis_ss(s, t)) {
		for (int k = 0; k < 2; ++k) {
			for (int l = 0; l < 2; ++l) {
				if (s[k] == t[l])return s[k];
			}
		}
		return is_ll(s, t);
	}
	else {
		//先にisis_ssしてね
		assert(false);
		return Point(0, 0);
	}
}
// 線分と線分の交点
vector<Point> is_ss2(const Line &s, const Line& t) {
	vector<Point> kouho(is_ll2(s, t));
	vector<Point>ans;
	for (auto p : kouho) {
		if (isis_sp(s, p) && isis_sp(t, p))ans.emplace_back(p);
	}
	return ans;
}
// 直線と点の距離
ld dist_lp(const Line& l, const Point& p) {
	return abs(p - proj(l, p));
}

//直線と直線の距離
ld dist_ll(const Line& l, const Line& m) {
	return isis_ll(l, m) ? 0 : dist_lp(l, m.a);
}

// 直線と線分の距離
ld dist_ls(const Line& l, const Line& s) {
	return isis_ls(l, s) ? 0 : min(dist_lp(l, s.a), dist_lp(l, s.b));
}

// 線分と点の距離
ld dist_sp(const Line& s, const Point& p) {
	Point r = proj(s, p);
	return isis_sp(s, r) ? abs(r - p) : min(abs(s.a - p), abs(s.b - p));
}

// 線分と線分の距離
ld dist_ss(const Line& s, const Line& t) {
	if (isis_ss(s, t)) return 0;
	return min({ dist_sp(s, t.a), dist_sp(s, t.b), dist_sp(t, s.a), dist_sp(t, s.b) });
}


//直線と直線の二等分線のベクトル
Line line_bisection(const Line &s, const Line &t) {
	const Point laglanju(is_ll(s, t));
	const Point avec = !(abs(laglanju - s[0])<eps) ? s[0] - laglanju : s[1] - laglanju;
	const Point bvec = !(abs(laglanju - t[0])<eps) ? t[0] - laglanju : t[1] - laglanju;

	return Line(laglanju, laglanju + (abs(bvec)*avec + abs(avec)*bvec) / (abs(avec) + abs(bvec)));
}
//点と点の垂直二等分線　aを左に見ながら
Line point_bisection(const Point&a, const Point&b) {
	const Point cen((a + b) / 2.l);
	const Point vec = (b - a)*Point(0, 1);
	return Line(cen, cen + vec);
}

//三つの点からなる外心
Point outer_center(const vector<Point>&ps) {
	assert(ps.size() == 3);
	Line l1 = point_bisection(ps[0], ps[1]);
	Line l2 = point_bisection(ps[1], ps[2]);
	return is_ll(l1, l2);
}


//三つの直線からなる内心
//三つの直線が並行でないことは確かめといてね
Point  inner_center(const vector<Line>&ls) {
	vector<Point>vertics;
	for (int i = 0; i <static_cast<int>(ls.size()); ++i) {
		vertics.push_back(is_ll(ls[i], ls[(i + 1) % 3]));
	}
	if (vertics[0] == vertics[1] || vertics[1] == vertics[2] || vertics[2] == vertics[0])return vertics[0];
	Line bi1(line_bisection(Line(vertics[0], vertics[1]), Line(vertics[0], vertics[2])));
	Line bi2(line_bisection(Line(vertics[1], vertics[2]), Line(vertics[1], vertics[0])));
	if (bi1[0] == bi2[0])return bi1[0];
	else {
		return is_ll(bi1, bi2);
	}
}

//三つの直線からなる傍心
//三つの直線が並行でないことは確かめといてね
vector<Point>  ex_center(const vector<Line>&ls) {
	vector<Point>vertics;
	for (int i = 0; i < static_cast<int>(ls.size()); ++i) {
		vertics.push_back(is_ll(ls[i], ls[(i + 1) % 3]));
	}
	if (abs(vertics[0] - vertics[1])<eps || abs(vertics[1] - vertics[2])<eps || (abs(vertics[2] - vertics[0])<eps))return vector<Point>();
	vector<Point>ecs;
	for (int i = 0; i < 3; ++i) {
		Line bi1(line_bisection(Line(vertics[i], vertics[i] * 2.0l - vertics[(i + 2) % 3]), Line(vertics[i], vertics[(i + 1) % 3])));
		Line bi2(line_bisection(Line(vertics[(i + 1) % 3], vertics[(i + 1) % 3] * 2.0l - vertics[(i + 2) % 3]), Line(vertics[(i + 1) % 3], vertics[i])));
		ecs.push_back(is_ll(bi1, bi2));
	}
	return ecs;
}


//a,b:並行
//c:並行でない
//三つの直線から同距離の位置を求める。
vector<Point>  same_dis(const vector<Line>&ls) {
	vector<Point>vertics;
	vertics.push_back(is_ll(ls[0], ls[2]));
	vertics.push_back(is_ll(ls[1], ls[2]));

	if (abs(vertics[0] - vertics[1]) < eps)return vector<Point>{vertics[0]};
	Line bis(line_bisection(ls[0], ls[1]));
	vector<Point>ecs;

	Line abi(line_bisection(Line(vertics[0], vertics[1]), ls[0]));
	ecs.push_back(is_ll(bis, abi));


	Line bbi(line_bisection(Line(vertics[0], 2.l*vertics[0] - vertics[1]), ls[0]));
	ecs.push_back(is_ll(bis, bbi));

	return ecs;
}
/* 円 */

// 円と円の交点
vector<Point> is_cc(const Circle& c1, const Circle& c2) {
	vector<Point> res;
	ld d = abs(c1.p - c2.p);
	ld rc = (d * d + c1.r * c1.r - c2.r * c2.r) / (2 * d);
	ld dfr = c1.r * c1.r - rc * rc;
	if (abs(dfr) < eps) dfr = 0.0;
	else if (dfr < 0.0) return res; // no intersection
	ld rs = sqrt(dfr);
	Point diff = (c2.p - c1.p) / d;
	res.push_back(c1.p + diff * Point(rc, rs));
	if (dfr != 0.0) res.push_back(c1.p + diff * Point(rc, -rs));
	return res;
}

/*
点が円の中にいるか
0 => out
1 => on
2 => in*/
int is_in_Circle(const  Point& p, const Circle &cir) {
	ld dis = abs(cir.p - p);
	if (dis > cir.r + eps)return 0;
	else if (dis < cir.r - eps)return 2;
	else return 1;
}
int is_in_Circle(const Circle &cir, const  Point& p) {
	ld dis = abs(cir.p - p);
	if (dis > cir.r + eps)return 0;
	else if (dis < cir.r - eps)return 2;
	else return 1;
}
/*
円lcが円rcの中にいるか
0 => out
1 => on
2 => in*/
int Circle_in_Circle(const Circle &lc, const  Circle&rc) {
	ld dis = abs(lc.p - rc.p);
	if (dis < rc.r - lc.r - eps)return 2;
	else if (dis>rc.r - lc.r + eps)return 0;
	else return 1;
}

// 円と直線の交点
vector<Point> is_lc(const Circle& c, const Line& l) {
	vector<Point> res;
	ld d = dist_lp(l, c.p);
	if (d < c.r + eps) {
		ld len = (d > c.r) ? 0.0 : sqrt(c.r * c.r - d * d); //safety;
		Point nor = (l.a - l.b) / abs(l.a - l.b);
		res.push_back(proj(l, c.p) + len * nor);
		res.push_back(proj(l, c.p) - len * nor);
	}
	return res;
}

// 円と線分の距離
vector<Point> is_sc(const Circle& c, const Line& l) {
	vector<Point> v = is_lc(c, l), res;
	for (Point p : v)
		if (isis_sp(l, p)) res.push_back(p);
	return res;
}

// 円と点の接線
vector<Line> tangent_cp(const Circle& c, const Point& p) {
	vector<Line> ret;
	Point v = c.p - p;
	ld d = abs(v);
	ld l = sqrt(norm(v) - c.r * c.r);
	if (isnan(l)) { return ret; }
	Point v1 = v * Point(l / d, c.r / d);
	Point v2 = v * Point(l / d, -c.r / d);
	ret.push_back(Line(p, p + v1));
	if (l < eps) return ret;
	ret.push_back(Line(p, p + v2));
	return ret;
}

// 円と円の接線
vector<Line> tangent_cc(const Circle& c1, const Circle& c2) {
	vector<Line> ret;
	if (abs(c1.p - c2.p) - (c1.r + c2.r) > -eps) {
		Point center = (c1.p * c2.r + c2.p * c1.r) / (c1.r + c2.r);
		ret = tangent_cp(c1, center);
	}
	if (abs(c1.r - c2.r) > eps) {
		Point out = (-c1.p * c2.r + c2.p * c1.r) / (c1.r - c2.r);
		vector<Line> nret = tangent_cp(c1, out);
		ret.insert(ret.end(), nret.begin(), nret.end());
	}
	else {
		Point v = c2.p - c1.p;
		v /= abs(v);
		Point q1 = c1.p + v * Point(0, 1) * c1.r;
		Point q2 = c1.p + v * Point(0, -1) * c1.r;
		ret.push_back(Line(q1, q1 + v));
		ret.push_back(Line(q2, q2 + v));
	}
	return ret;
}
//二つの円の重なり面積
ld two_Circle_area(const Circle&l, const Circle&r) {
	ld dis = abs(l.p - r.p);
	if (dis > l.r + r.r)return 0;
	else if (dis + r.r < l.r) {
		return r.r*r.r*pi;
	}
	else if (dis + l.r < r.r) {
		return l.r*l.r*pi;
	}
	else {
		ld ans = (l.r)*(l.r)*acos((dis*dis + l.r*l.r - r.r*r.r) / (2 * dis*l.r)) +
			(r.r)*(r.r)*acos((dis*dis + r.r*r.r - l.r*l.r) / (2 * dis*r.r)) -
			sqrt(4 * dis*dis*l.r*l.r - (dis*dis + l.r*l.r - r.r*r.r)*(dis*dis + l.r*l.r - r.r*r.r)) / 2;
		return ans;
	}

}

/* 多角形 */

typedef vector<Point> Polygon;



//多角形(複数の点)の最小包含円をO(N=頂点数)で求めるアルゴリズム
//同一直線上に三つの点がないこと
#include<random>
Circle welzl(vector<Point>ps) {
	struct solver {
		Circle solve(vector<Point>&ps, vector<Point>&rs) {
			if (ps.empty() || rs.size() == 3) {
				if (rs.size() == 1) {
					return Circle(Point(rs[0]), 0);
				}
				else if (rs.size() == 2) {
					return Circle((rs[0] + rs[1]) / 2.0l, abs(rs[1] - rs[0]) / 2);
				}
				else if (rs.size() == 3) {
					vector<Line> ls(3);
					for (int i = 0; i < 3; ++i) {
						ls[i] = Line(rs[i], rs[(i + 1) % 3]);
					}
					Point center = outer_center(rs);
					return Circle(center, abs(center - rs[0]));
				}
				else {
					return Circle(Point(), 0);
				}
			}
			else {

				Point p_ba = ps.back();
				ps.pop_back();
				Circle d = solve(ps, rs);
				ps.push_back(p_ba);
				if (is_in_Circle(d, p_ba)) {
					return d;
				}
				else {
					rs.push_back(p_ba);
					ps.pop_back();
					auto ans = solve(ps, rs);
					ps.push_back(p_ba);
					rs.pop_back();
					return ans;
				}
			}
		}
	}so;
	std::random_device rd;
	std::mt19937 mt(rd());
	shuffle(ps.begin(), ps.end(), mt);
	vector<Point>rs;
	Circle ans = so.solve(ps, rs);
	return ans;
}
// 面積
ld get_area(const Polygon &p) {
	ld res = 0;
	int n = p.size();
	for (int j = 0; j<n; ++j) res += cross(p[j], p[(j + 1) % n]);
	return res / 2;
}

//多角形の回転方向
bool is_counter_clockwise(const Polygon &poly) {
	ld angle = 0;
	int n = poly.size();
	for(int i=0;i<n;++i) {
		Point a = poly[i], b = poly[(i + 1) % n], c = poly[(i + 2) % n];
		angle += arg((c - b) / (b - a));
	}
	return angle > eps;
}

// 円の内外判定
/*0 => out
1 => on
2 => in*/
int is_in_Polygon(const Polygon &poly, const  Point& p) {
	ld angle = 0;
	int n = poly.size();
	for(int i=0;i<n;++i) {
		Point a = poly[i], b = poly[(i + 1) % n];
		if (isis_sp(Line(a, b), p)) return 1;
		angle += arg((b - p) / (a - p));
	}
	return eq(angle, 0) ? 0 : 2;
}
//円の内外判定2　高速
enum { out, on, in };
int convex_contains(const Polygon &P, const Point &p) {
	const int n = P.size();
	Point g = (P[0] + P[n / 3] + P[2 * n / 3]) / 3.0l; // inner-point
	int a = 0, b = n;
	while (a + 1 < b) { // invariant: c is in fan g-P[a]-P[b]
		int c = (a + b) / 2;
		if (cross(P[a] - g, P[c] - g) > 0) { // angle < 180 deg
			if (cross(P[a] - g, p - g) > 0 && cross(P[c] - g, p - g) < 0) b = c;
			else                                                  a = c;
		}
		else {
			if (cross(P[a] - g, p - g) < 0 && cross(P[c] - g, p - g) > 0) a = c;
			else                                                  b = c;
		}
	}
	b %= n;
	if (cross(P[a] - p, P[b] - p) < 0) return 0;
	if (cross(P[a] - p, P[b] - p) > 0) return 2;
	return 1;
}

// 凸包
//点や線を返すことも有り得るので注意
Polygon convex_hull(vector<Point> ps) {
	int n = ps.size();
	int k = 0;
	sort(ps.begin(), ps.end());
	Polygon ch(2 * n);
	for (int i = 0; i < n; ch[k++] = ps[i++])
		while (k >= 2 && ccw(ch[k - 2], ch[k - 1], ps[i]) <= 0) --k;
	for (int i = n - 2, t = k + 1; i >= 0; ch[k++] = ps[i--])
		while (k >= t && ccw(ch[k - 2], ch[k - 1], ps[i]) <= 0) --k;
	ch.resize(k - 1);
	return ch;
}



//凸カット
vector<Polygon> convex_cut(const Polygon &ps, const Line& l) {
	int n = ps.size();
	Polygon q;
	Polygon r;
	for(int i=0;i<n;++i) {
		Point a = ps[i], b = ps[(i + 1) % n];
		Line m = Line(a, b);
		if (ccw(l.a, l.b, a) != -1) q.push_back(a);
		if (ccw(l.a, l.b, a) != 1) r.push_back(a);
		if (ccw(l.a, l.b, a) * ccw(l.a, l.b, b) < 0 && isis_ll(l, m)) {
			q.push_back(is_ll(l, m));
			r.push_back(is_ll(l, m));
		}
	}
	const vector<Polygon>polys{ q,r };
	return polys;
}

int main() {
	while (true) {
		int N;cin>>N;
		if(!N)break;
		vector<ld>us,ds,ls,rs;
		for (int i = 0; i < N; ++i) {
			ld n;cin>>n;
			ds.push_back(n);
		}
		for (int i = 0; i < N; ++i) {
			ld n; cin >> n;
			us.push_back(n);
		}
		for (int i = 0; i < N; ++i) {
			ld n; cin >> n;
			ls.push_back(n);
		}
		for (int i = 0; i < N; ++i) {
			ld n; cin >> n;
			rs.push_back(n);
		}

		Polygon start_poly{
			Point(0,0),
			Point(1,0),
			Point(1,1),
			Point(0,1)
		};

		vector<Polygon>polys{ start_poly };
		for (int i = 0; i < N; ++i) {
			vector<Polygon>nextpolys;
			for (auto po : polys) {
				Line l(Point(ds[i],0),Point(us[i],1));
				auto pos=convex_cut(po,l);

				for (auto aa : pos) {
					if (abs(get_area(aa)) > eps) {

						nextpolys.push_back(aa);
					}
				}
			}
			polys=nextpolys;
		}
		for (int i = 0; i < N; ++i) {
			vector<Polygon>nextpolys;
			for (auto po : polys) {
				Line l(Point(0,ls[i]), Point(1,rs[i]));
				auto pos = convex_cut(po, l);

				for (auto aa : pos) {
					if (abs(get_area(aa)) > eps) {

						nextpolys.push_back(aa);
					}
				}
			}
			polys = nextpolys;
		}
		ld ans=0;
		for (auto poly : polys) {
			ans=max(ans,abs(get_area(poly)));
		}
		cout<<setprecision(6)<<fixed<<ans<<endl;
	}
	return 0;
}
accuracy: 1
time_ms: 240
memory_kb: 3560
final_rank: 6

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define int long long
#define EPS (1e-10)
struct Point{
  double x,y;
  Point(){}
  Point(double x,double y):x(x),y(y){}
  Point operator+(Point a){return Point(x+a.x,y+a.y);}
  Point operator-(Point a){return Point(x-a.x,y-a.y);}
  Point operator*(double k){return Point(x*k,y*k);}
  Point operator/(double k){return Point(x/k,y/k);}
};
typedef Point Vector;
typedef vector<Point> Polygon;
struct Segment{
  Point p1,p2;
  Segment(){}
  Segment(Point p1,Point p2):p1(p1),p2(p2){}
};
typedef Segment Line;
double norm(Point a){
  return a.x*a.x+a.y*a.y;
}
double abs(Point a){
  return sqrt(norm(a));
}
double dot(Point a,Point b){
  return a.x*b.x+a.y*b.y;
}
double cross(Point a,Point b){
  return a.x*b.y-a.y*b.x;
}
const double PI=3.141592653589793238;
Point trans(double k){
  return Point(cos(k*2*PI),sin(k*2*PI));
}
int ccw(Point p0,Point p1,Point p2){
  Vector a=p1-p0;
  Vector b=p2-p0;
  if(cross(a,b)>EPS) return 1;
  if(cross(a,b)<-EPS) return -1;
  if(dot(a,b)<-EPS) return 2;
  if(norm(a)<norm(b)) return -2;
  return 0;
}
Point getCrossPointLL(Line l1,Line l2){
  double a=cross(l1.p2-l1.p1,l2.p2-l2.p1);
  double b=cross(l1.p2-l1.p1,l1.p2-l2.p1);
  if(abs(a)<EPS&&abs(b)<EPS) return l2.p1;
  return l2.p1+(l2.p2-l2.p1)*(b/a);
}
Polygon convexCut(Polygon p,Line l){
  Polygon q;
  for(int i=0;i<(int)p.size();i++){
    Point a=p[i],b=p[(i+1)%p.size()];
    if(ccw(l.p1,l.p2,a)!=-1) q.push_back(a);
    if(ccw(l.p1,l.p2,a)*ccw(l.p1,l.p2,b)<0)
      q.push_back(getCrossPointLL(Line(a,b),l));
  }
  return q;
}
double area(Polygon s){
  double res=0;
  for(int i=0;i<(int)s.size();i++){
    res+=cross(s[i],s[(i+1)%s.size()])/2.0;
  }
  return abs(res);
}
int n,m;
Polygon a,b,c,d;
signed main(){
  while(cin>>n,n){
    a.clear();
    b.clear();
    c.clear();
    d.clear();
    double k;
    a.push_back(Point(0,0));
    b.push_back(Point(0,1));
    c.push_back(Point(0,0));
    d.push_back(Point(1,0));
    for(int i=0;i<n&&cin>>k;i++) a.push_back(Point(k,0));
    for(int i=0;i<n&&cin>>k;i++) b.push_back(Point(k,1));
    for(int i=0;i<n&&cin>>k;i++) c.push_back(Point(0,k));
    for(int i=0;i<n&&cin>>k;i++) d.push_back(Point(1,k));
    a.push_back(Point(1,0));
    b.push_back(Point(1,1));
    c.push_back(Point(0,1));
    d.push_back(Point(1,1));
    double ans=0;
    Polygon ba(4);
    ba[0]=Point(0,0);
    ba[1]=Point(1,0);
    ba[2]=Point(1,1);
    ba[3]=Point(0,1);
    for(int i=0;i<n+1;i++){
      for(int j=0;j<n+1;j++){
	Polygon t(ba);
	t=convexCut(t,Line(b[i],a[i]));
	t=convexCut(t,Line(a[i+1],b[i+1]));
	t=convexCut(t,Line(c[j],d[j]));
	t=convexCut(t,Line(d[j+1],c[j+1]));
	ans=max(ans,area(t));
      }
    }  
    printf("%.6f\n",ans);
  }
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3068
final_rank: 4

code_snippet: #include <vector>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <deque>
#include <stack>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
using namespace std;
#define REP(i,n) for(int i = 0; i < (int)n; i++)
#define FOR(i,a,b) for(int i = a; i < (int)b; i++)
#define pb push_back
#define mp make_pair
typedef vector<int> vi;
typedef pair<int, int> pi;
typedef long long ll;
typedef unsigned long long ull;
const int IINF = 1<<28;
const ll MOD = 1000000007;
const int dx[] = {1, 0, -1, 0}, dy[] = {0, 1, 0, -1};

// Geometric Library
#include <complex>
#define curr(P, i) P[i]
#define next(P, i) P[(i+1)%P.size()]
typedef complex<double> P;
typedef vector<P> G;
const double EPS = 1e-8;
const double INF = 1e12;
namespace std {
	bool operator < (const P& a, const P& b) {
		//return real(a) != real(b) ? real(a) < real(b) : imag(a) < imag(b);
		if(imag(a) < imag(b))
			return true;
		if(imag(a) == imag(b) && real(a) < real(b))
			return true;
		return false;
	}
}
double cross(const P& a, const P& b) { return imag(conj(a)*b); }
double dot(const P& a, const P& b) { return real(conj(a)*b); }
struct L : public vector<P> {
	L(const P &a, const P &b) {
		push_back(a); push_back(b);
	}
};
int ccw(P a, P b, P c) {
	b -= a; c -= a;
	if (cross(b, c) > 0) return +1; // counter clockwise
	if (cross(b, c) < 0) return -1; // clockwise
	if (dot(b, c) < 0) return +2; // c--a--b on line
	if (norm(b) < norm(c)) return -2; // a--b--c on line
	return 0;
}
P crosspoint(const L &l, const L &m) {
	double A = cross(l[1] - l[0], m[1] - m[0]);
	double B = cross(l[1] - l[0], l[1] - m[0]);
	if (abs(A) < EPS && abs(B) < EPS) return m[0]; // same line
	return m[0] + B / A * (m[1] - m[0]);
}
G convex_cut(const G& g, const L& l) {
	G Q;
	for (int i = 0; i < g.size(); ++i) {
		P A = curr(g, i), B = next(g, i);
		if (ccw(l[0], l[1], A) != -1) Q.push_back(A);
		if (ccw(l[0], l[1], A)*ccw(l[0], l[1], B) < 0)
		Q.push_back(crosspoint(L(A, B), l));
	}
	return Q;
}
double area2(const G& g) {
	double A = 0;
	for (int i = 0; i < g.size(); ++i) 
		A += cross(curr(g, i), next(g, i));
	return A / 2.0;
}

int main() {
	ios_base::sync_with_stdio(0);
	cin.tie(0);


	int n;
	while(cin >> n, n) {
		vector<G> v(n+2);
		REP(i, 4) {
			REP(j, n) {
				double in; cin >> in;
				if(i == 0)
					v[0].pb(P(0, in));
				else if(i == 1)
					v[n+1].pb(P(1, in));
				else if(i == 2)
					v[j+1].pb(P(in, 0));
				else if(i == 3)
					v[j+1].pb(P(in, 1));
			}
		}
		REP(i, n)
			REP(j, n)
				v[i+1].pb(crosspoint(L(v[i+1][0], v[i+1][1]), L(v[0][j], v[n+1][j])));
		v[0].pb(P(0, 0)); v[0].pb(P(0, 1));
		v[n+1].pb(P(1, 0)); v[n+1].pb(P(1, 1));
		REP(i, n+2)
			sort(v[i].begin(), v[i].end());
		double ans = 0;
		REP(i, n+1) {
			REP(j, n+1) {
				G g;
				g.pb(v[i][j]);
				g.pb(v[i+1][j]);
				g.pb(v[i+1][j+1]);
				g.pb(v[i][j+1]);
				ans = max(ans, area2(g));
			}
		}
		cout << ans << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 1328
final_rank: 3

code_snippet: #include <string> 
#include <algorithm> 
#include <cfloat> 
#include <climits> 
#include <cmath> 
#include <complex> 
#include <cstdio> 
#include <cstdlib> 
#include <cstring> 
#include <functional> 
#include <iostream> 
#include <map> 
#include <memory> 
#include <queue> 
#include <set> 
#include <sstream> 
#include <stack> 
#include <utility> 
#include <vector> 

#define EACH(i,c) for(typeof((c).begin()) i=(c).begin(); i!=(c).end(); ++i)
#define ALL(x) (x).begin(),(x).end() 
typedef long long ll;
using namespace std; 
const double eps = 1e-10;

const int MAX_N = 30;

typedef complex<double> P;

bool operator < (const P &a, const P &b){
    return a.real() != b.real() ? a.real() < b.real() : a.imag() < b.imag();
}
double dot(const P &a, const P &b){
    return real(conj(a) * b);
}
double cross(const P &a, const P &b){
    return imag(conj(a) * b);
}

struct Line : public vector<P> {
    Line(const P &a, const P &b) {
        push_back(a); push_back(b);
    }
    Line(double x1, double y1, double x2, double y2){
        push_back(P(x1, y1));
        push_back(P(x2, y2));
    }
};

typedef vector<P> Polygon;

struct Circle{
    P p; double r;
    Circle(const P &p, double r) : p(p), r(r) { }
};

P intersection_ls(const Line &a, const Line &b){
    P vb = b[1] - b[0];
    double d1 = abs(cross(vb, a[0] - b[0]));
    double d2 = abs(cross(vb, a[1] - b[0]));
    double t = d1 / (d1 + d2);
    return a[0] + (a[1] - a[0]) * t;
}

int n;
double a[MAX_N], b[MAX_N], c[MAX_N], d[MAX_N];
void solve(){
    double res = 0.0;
    a[0] = b[0] = c[0] = d[0] = 0.0;
    a[n + 1] = b[n + 1] = c[n + 1] = d[n + 1] = 1.0;
    for(int i = 0; i <= n; ++i){
        for(int j = 0; j <= n; ++j){
            Line l1 = Line(a[i], 0, b[i], 1);
            Line l2 = Line(a[i + 1], 0, b[i + 1], 1);
            Line l3 = Line(0, c[j], 1, d[j]);
            Line l4 = Line(0, c[j + 1], 1, d[j + 1]);
            P p1 = intersection_ls(l1, l3);
            P p2 = intersection_ls(l1, l4);
            P p3 = intersection_ls(l2, l3);
            P p4 = intersection_ls(l2, l4);
            double tmp = (abs(cross(p2 - p1, p3 - p1)) + abs(cross(p3 - p4, p2 - p4))) / 2.0;
            res = max(res, tmp);
        }
    }
    printf("%.9f\n", res);
}
int main(){
    while(cin >> n, n){
        for(int i = 1; i <= n; ++i) cin >> a[i];
        for(int i = 1; i <= n; ++i) cin >> b[i];
        for(int i = 1; i <= n; ++i) cin >> c[i];
        for(int i = 1; i <= n; ++i) cin >> d[i];
        solve();
    }
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 0
final_rank: 1

code_snippet: #include<iostream>
#include<cfloat>
#include<cassert>
#include<cmath>
#include<vector>

using namespace std;

#define EPS (1e-10)
#define equals(a, b) (fabs((a) - (b)) < EPS )
#define dle(a, b) (equals(a, b) || a < b )
static const double PI = acos(-1);

class Point{
    public:
    double x, y;
    
    Point ( double x = 0, double y = 0): x(x), y(y){}
    
    Point operator + ( Point p ){ return Point(x + p.x, y + p.y); }
    Point operator - ( Point p ){ return Point(x - p.x, y - p.y); }
    Point operator * ( double a ){ return Point(x*a, y*a); }
    Point operator / ( double a ){ return Point(x/a, y/a); }

    double abs() { return sqrt(norm());}
    double norm() { return x*x + y*y; }

    bool operator < ( const Point &p ) const {
	return x != p.x ? x < p.x : y < p.y;
    }

    bool operator == ( const Point &p ) const {
	return fabs(x-p.x) < EPS && fabs(y-p.y) < EPS;
    }
};

typedef Point Vector;

class Segment{
    public:
    Point p1, p2;
    Segment(Point s = Point(), Point t = Point()): p1(s), p2(t){}
};

typedef vector<Point> Polygon;

double norm( Vector a ){ return a.x*a.x + a.y*a.y; }
double abs( Vector a ){ return sqrt(norm(a)); }
Point polar( double a, double r ){ return Point(cos(r)*a, sin(r)*a);}
double getDistance( Vector a, Vector b ){ return abs(a - b); }
double dot( Vector a, Vector b ){ return a.x*b.x + a.y*b.y; }
double cross( Vector a, Vector b ){ return a.x*b.y - a.y*b.x; }

static const int COUNTER_CLOCKWISE = 1;
static const int CLOCKWISE = -1;
static const int ONLINE_BACK = 2;
static const int ONLINE_FRONT = -2;
static const int ON_SEGMENT = 0;

int ccw( Point p0, Point p1, Point p2 ){
    Vector a = p1 - p0;
    Vector b = p2 - p0;
    if ( cross(a, b) > EPS ) return COUNTER_CLOCKWISE;
    if ( cross(a, b) < -EPS ) return CLOCKWISE;
    if ( dot(a, b) < -EPS ) return ONLINE_BACK;
    if ( norm(a) < norm(b) ) return ONLINE_FRONT;
    return ON_SEGMENT;
}

bool isIntersect(Point p1, Point p2, Point p3, Point p4){
    return ( ccw(p1, p2, p3) * ccw(p1, p2, p4) <= 0 &&
	     ccw(p3, p4, p1) * ccw(p3, p4, p2) <= 0 );
}

bool isIntersect(Segment s1, Segment s2){
    return isIntersect(s1.p1, s1.p2, s2.p1, s2.p2);
}

Point getCrossPoint(Segment s1, Segment s2){
    assert( isIntersect(s1, s2) );
    Vector base = s2.p2 - s2.p1;
    double d1 = abs(cross(base, s1.p1 - s2.p1));
    double d2 = abs(cross(base, s1.p2 - s2.p1));
    double t = d1/(d1 + d2);
    return s1.p1 + (s1.p2 - s1.p1)*t;
}

double getArea(Polygon p){
    double sum = 0.0;
    for(int i = 0; i < p.size(); i++){
	sum += cross(p[i], p[(i+1)%p.size()]);
    }
    return abs(sum/2);
}

#define MAX 30

int main(){
    double a[MAX+2], b[MAX+2], c[MAX+2], d[MAX+2];
    int n;
    Segment V[MAX+2], H[MAX+2];

    Point P[MAX+2][MAX+2];

    while( cin >> n && n ){
	for ( int i = 1; i <= n; i++ ) cin >> a[i];
	for ( int i = 1; i <= n; i++ ) cin >> b[i];
	for ( int i = 1; i <= n; i++ ) cin >> c[i];
	for ( int i = 1; i <= n; i++ ) cin >> d[i];

	V[0] = Segment(Point(0, 0), Point(0, 1));
	for ( int i = 1; i <= n; i++ ){
	    V[i] = Segment(Point(a[i], 0), Point(b[i], 1));
	}
	V[n+1] = Segment(Point(1, 0), Point(1, 1));

	H[0] = Segment(Point(0, 0), Point(1, 0));
	for ( int i = 1; i <= n; i++ ){
	    H[i] = Segment(Point(0, c[i]), Point(1, d[i]));
	}
	H[n+1] = Segment(Point(0, 1), Point(1, 1));

	
	for ( int y = 0; y < n+2; y++ ){
	    for ( int x = 0; x < n+2; x++ ){
		P[y][x] = getCrossPoint(H[y], V[x]);
	    }
	}

	double maxa = 0;

	for ( int y = 1; y < n+2; y++ ){
	    for ( int x = 1; x < n+2; x++ ){
		Polygon S;
		S.push_back(P[y][x]);
		S.push_back(P[y][x-1]);
		S.push_back(P[y-1][x-1]);
		S.push_back(P[y-1][x]);
		maxa = max( maxa, getArea(S) );
	    }
	}

	printf("%.12lf\n", maxa);
    }



    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 0
final_rank: 1