Problem:
アリの巣箱の形状
求悟君は夏休みの自由研究としてアリの巣の観察を行うことにしました。彼のおじいちゃんが孫のために用意してくれた観察用の透明ケースはとてもユニークで、図1のような形をしています。
図１
このケースは、2枚の合同な凸多角形 s1、s2 と何枚かの長方形で構成されています。s1、s2 以外のいずれかの長方形の面を床に接するように置きます。観察を始めた求悟君は、入っている土の量が同じにもかかわらず、底面の選び方によって土の高さが変わることに気付きました（図2）。
図２
求悟君は、ケースの置き方によって、どのくらい高くなるか知りたくなりました。凸多角形 s1 の形、s1 と s2 間の距離
d
、土の体積
V
を入力とし、土の高さの最大値を出力するプログラムを作成してください。土は、ケースの底面を床に置くとすぐに水平になるものとします。透明ケースの s1 の形は、二次元の座標平面上の
n
個の頂点で与えられます。これらの頂点は、反時計回りの順番で入力されます。
n
は 3 以上 100 以下で、
d
と
V
はそれぞれ 1 以上 10,000 以下の整数とします。また、多角形の頂点の座標
(x, y)
の
x
、
y
はそれぞれ -1,000 以上 1,000 以下の整数とします。
V
はケースの体積を超えません。
入力
複数のデータセットの並びが入力として与えられます。入力の終わりはゼロみっつの行で示されます。各データセットは以下のとおりです。
1 行目
n
d
V
（整数 整数 整数；半角空白区切り）
2 行目 第 1 の頂点の座標
x
y
（整数 整数；半角空白区切り）
3 行目 第 2 の頂点の座標
:
n+1
行目 第
n
の頂点の座標
データセットの数は 20 を超えません。
出力
入力データセットごとに、土の高さの最大値を出力します。答えには 0.00001 を越える誤差があってはいけません。
入力例
4 1 1
0 0
1 0
1 2
0 2
0 0 0
出力例
1.000000

Submitted solutions:

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 1000000000000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;



struct Point{
	Point(double arg_x,double arg_y){
		x = arg_x;
		y = arg_y;
	}

	Point(){
		x = y = 0.0;
	}

	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(a*x,a*y); }
	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;
	}

   	void debug(){

		printf("(%.3lf,%.3lf)\n",x,y);
	}

	double x,y;
};

typedef Point Vector;
typedef vector<Point> Polygon;

struct Line{
	Line(){

	}
	Line(Point a,Point b){
		p[0] = a;
		p[1] = b;
	}
	/*void outPut(){

		printf("(%.3lf,%.3lf)-(%.3lf,%.3lf)\n",p[0].x,p[0].y,p[1].x,p[1].y);
	}*/
	Point p[2];
};

int N;
double D,V;
double NUM = 10000;
double RAD[105];


double calc_dist(Point A,Point B){

	return sqrt((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y));
}


int func(double x1,double y1,double x2, double y2, double xp, double yp){
	double naiseki,norm1,norm2,gaiseki;
	norm1 = sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
	norm2 = sqrt((xp-x1)*(xp-x1)+(yp-y1)*(yp-y1));
	naiseki = (xp-x1)*(x2-x1)+(yp-y1)*(y2-y1);
	gaiseki = (x2-x1)*(yp-y1)-(xp-x1)*(y2-y1);
	if(gaiseki > EPS){
		return 1;
	}else if(gaiseki < -EPS){
		return -1;
	}
	if(naiseki < -EPS){
		return 2;
	}

	if(norm1 < norm2){
		return -2;
	}
	return 0;
}


//★★直線ではなく、線分の交差判定★★
bool is_Cross(Line a,Line b){

	if(func(a.p[0].x,a.p[0].y,a.p[1].x,a.p[1].y,b.p[0].x,b.p[0].y)*
			func(a.p[0].x,a.p[0].y,a.p[1].x,a.p[1].y,b.p[1].x,b.p[1].y) <= 0 &&
			func(b.p[0].x,b.p[0].y,b.p[1].x,b.p[1].y,a.p[0].x,a.p[0].y)*
			func(b.p[0].x,b.p[0].y,b.p[1].x,b.p[1].y,a.p[1].x,a.p[1].y) <= 0){
		return true;
	}
	return false;
}


Point calc_minus(Point a,Point b){
    Point ret;

    ret.x = a.x-b.x;
    ret.y = a.y-b.y;

    return ret;
}

double calc_len(Vector a){
    return sqrt(a.x*a.x+a.y*a.y);
}

double calc_slope(Line A){

	if(fabs(A.p[0].x-A.p[1].x) < EPS){

		return DBL_MAX;

	}else if(fabs(A.p[0].y-A.p[1].y) < EPS){

		return 0;

	}else{

		return (A.p[0].y-A.p[1].y)/(A.p[0].x-A.p[1].x);
	}
}

double norm(Vector a){
	return a.x*a.x+a.y*a.y;
}

double abs(Vector a){
	return sqrt(norm(a));
}

double cross(Vector a,Vector b){
    return a.x*b.y-a.y*b.x;
}

double dot(Vector a,Vector b){
    return a.x*b.x + a.y*b.y;
}

//線分ではなく直線と点の距離
double getDistanceLP(Line l,Point p){
    return fabs(cross(calc_minus(l.p[1],l.p[0]),calc_minus(p,l.p[0]))/calc_len(calc_minus(l.p[1],l.p[0])));
}

//点と線分の距離
double getDistanceSP(Line l,Point p){
	if(dot(calc_minus(l.p[1],l.p[0]),calc_minus(p,l.p[0])) < 0.0)return calc_len(calc_minus(p,l.p[0]));
	if(dot(calc_minus(l.p[0],l.p[1]),calc_minus(p,l.p[1])) < 0.0)return calc_len(calc_minus(p,l.p[1]));
	return getDistanceLP(l,p);
}

//線分と線分の距離
double getDistance(Line A,Line B){
	if(is_Cross(A,B))return 0.0;
	return min(min(getDistanceSP(A,B.p[0]),getDistanceSP(A,B.p[1])),
			min(getDistanceSP(B,A.p[0]),getDistanceSP(B,A.p[1])));
}

//交点を求める関数
Point calc_Cross_Point(double x1,double x2,double x3,double x4,double y1,double y2,double y3,double y4){
	Point ret;
	ret.x = ((x2-x1)*(y3*(x4-x3)+x3*(y3-y4))-(x4-x3)*(y1*(x2-x1)+x1*(y1-y2)))/((y2-y1)*(x4-x3)-(y4-y3)*(x2-x1));
	if(fabs(x1-x2) > EPS){
		ret.y = ((y2-y1)*ret.x+y1*(x2-x1)+x1*(y1-y2))/(x2-x1);
	}else{
		ret.y = ((y4-y3)*ret.x+y3*(x4-x3)+x3*(y3-y4))/(x4-x3);
	}
	return ret;
}

//インタフェース関数
Point calc_Cross_Point(Point a,Point b,Point c,Point d){
	return calc_Cross_Point(a.x,b.x,c.x,d.x,a.y,b.y,c.y,d.y);
}

Point calc_Cross_Point(Line A,Line B){

	if(getDistanceSP(B,A.p[0]) < EPS){

		return A.p[0];

	}else if(getDistanceSP(B,A.p[1]) < EPS){

		return A.p[1];

	}else if(getDistanceSP(A,B.p[0]) < EPS){

		return B.p[0];

	}else if(getDistanceSP(A,B.p[1]) < EPS){

		return B.p[1];
	}

	return calc_Cross_Point(A.p[0],A.p[1],B.p[0],B.p[1]);
}

double calc_S(Polygon g){

	int N = g.size();
	double ret = 0;

	for(int i = 0; i < g.size(); i++){
		ret += cross(g[i],g[(i+1)%N]);
	}
	return ret/2.0;
}

double calc_bottomS(Polygon P,Line line){

	int count = 0;
	int N = P.size();

	int index_1 = -1,index_2;
	Point cross1,cross2;

	for(int i = 0; i < N; i++){

		Line tmp_line = Line(P[i],P[(i+1)%N]);
		if(is_Cross(tmp_line,line)){
			count++;
			if(index_1 == -1){

				index_1 = i;
				cross1 = calc_Cross_Point(tmp_line,line);

			}else{

				index_2 = i;
				cross2 =calc_Cross_Point(tmp_line,line);
			}
		}
	}

	if(count <= 1)return 0;

	Polygon A;
	for(int i = 0; i <= index_1; i++){

		A.push_back(P[i]);
	}
	A.push_back(cross1);
	A.push_back(cross2);

	for(int i = index_2+1; i < N; i++){

		A.push_back(P[i]);
	}

	return calc_S(A);
}

void func(){

	Polygon P;

	double x,y;
	for(int i = 0; i < N; i++){

		scanf("%lf %lf",&x,&y);

		P.push_back(Point(x,y));
	}

	for(int i = 0; i <= N-1; i++){

		Vector vec1 = P[(i-1+N)%N]-P[i];
		Vector vec2 = P[(i+1)%N]-P[i];

		RAD[i] = M_PI-acos(dot(vec1,vec2)/(abs(vec1)*abs(vec2)));
	}

	double ans = 0;

	Polygon work;

	for(int i = 0; i <= N-1; i++){

		double tmp_dist = calc_dist(P[i],P[(i+1)%N]);
		work.clear();

		work.push_back(Point(0,0)); //P[i]を(0,0)、P[(i+1)%N]を(tmp_dist,0)にする
		work.push_back(Point(tmp_dist,0));

		Point pre = work[1];
		double rad = 0;

		double L = 0,R = 0;

		for(int k = 0; k < N-2; k++){

			double tmp_dist = calc_dist(P[(i+1+k)%N],P[(i+2+k)%N]);

			rad += RAD[(i+1+k)%N];

			Vector tmp = Vector(tmp_dist*cos(rad),tmp_dist*sin(rad));

			Point next = pre+tmp;

			L = min(L,next.y);
			R = max(R,next.y);

			work.push_back(next);
			pre = next;
		}

		for(int loop = 0; loop < 100; loop++){

			double mid1 = (2.0*L+R)/3.0;
			double mid2 = (1.0*L+2.0*R)/3.0;

			Line tmp_line1 = Line(Point(-NUM,mid1),Point(NUM,mid1));
			Line tmp_line2 = Line(Point(-NUM,mid2),Point(NUM,mid2));

			double V1 = calc_bottomS(work,tmp_line1)*D;
			double V2 = calc_bottomS(work,tmp_line2)*D;

			if(fabs(V-V1) < fabs(V-V2)){

				R = mid2;

			}else{

				L = mid1;
			}
		}
		ans = max(ans,(L+R)/2);
	}

	printf("%.10lf\n",ans);
}

int main(){

	while(true){

		scanf("%d %lf %lf",&N,&D,&V);
		if(N == 0)break;

		func();
	}

	return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 3612
final_rank: 18

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 1000000000000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;



struct Point{
	Point(double arg_x,double arg_y){
		x = arg_x;
		y = arg_y;
	}

	Point(){
		x = y = 0.0;
	}

	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(a*x,a*y); }
	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;
	}

   	void debug(){

		printf("(%.3lf,%.3lf)\n",x,y);
	}

	double x,y;
};

typedef Point Vector;
typedef vector<Point> Polygon;

struct Line{
	Line(){

	}
	Line(Point a,Point b){
		p[0] = a;
		p[1] = b;
	}
	/*void outPut(){

		printf("(%.3lf,%.3lf)-(%.3lf,%.3lf)\n",p[0].x,p[0].y,p[1].x,p[1].y);
	}*/
	Point p[2];
};

int N;
double D,V;
double NUM = 10000;
double RAD[105];


double calc_dist(Point A,Point B){

	return sqrt((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y));
}


int func(double x1,double y1,double x2, double y2, double xp, double yp){
	double naiseki,norm1,norm2,gaiseki;
	norm1 = sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
	norm2 = sqrt((xp-x1)*(xp-x1)+(yp-y1)*(yp-y1));
	naiseki = (xp-x1)*(x2-x1)+(yp-y1)*(y2-y1);
	gaiseki = (x2-x1)*(yp-y1)-(xp-x1)*(y2-y1);
	if(gaiseki > EPS){
		return 1;
	}else if(gaiseki < -EPS){
		return -1;
	}
	if(naiseki < -EPS){
		return 2;
	}

	if(norm1 < norm2){
		return -2;
	}
	return 0;
}


//★★直線ではなく、線分の交差判定★★
bool is_Cross(Line a,Line b){

	if(func(a.p[0].x,a.p[0].y,a.p[1].x,a.p[1].y,b.p[0].x,b.p[0].y)*
			func(a.p[0].x,a.p[0].y,a.p[1].x,a.p[1].y,b.p[1].x,b.p[1].y) <= 0 &&
			func(b.p[0].x,b.p[0].y,b.p[1].x,b.p[1].y,a.p[0].x,a.p[0].y)*
			func(b.p[0].x,b.p[0].y,b.p[1].x,b.p[1].y,a.p[1].x,a.p[1].y) <= 0){
		return true;
	}
	return false;
}


Point calc_minus(Point a,Point b){
    Point ret;

    ret.x = a.x-b.x;
    ret.y = a.y-b.y;

    return ret;
}

double calc_len(Vector a){
    return sqrt(a.x*a.x+a.y*a.y);
}

double calc_slope(Line A){

	if(fabs(A.p[0].x-A.p[1].x) < EPS){

		return DBL_MAX;

	}else if(fabs(A.p[0].y-A.p[1].y) < EPS){

		return 0;

	}else{

		return (A.p[0].y-A.p[1].y)/(A.p[0].x-A.p[1].x);
	}
}

double norm(Vector a){
	return a.x*a.x+a.y*a.y;
}

double abs(Vector a){
	return sqrt(norm(a));
}

double cross(Vector a,Vector b){
    return a.x*b.y-a.y*b.x;
}

double dot(Vector a,Vector b){
    return a.x*b.x + a.y*b.y;
}

//線分ではなく直線と点の距離
double getDistanceLP(Line l,Point p){
    return fabs(cross(calc_minus(l.p[1],l.p[0]),calc_minus(p,l.p[0]))/calc_len(calc_minus(l.p[1],l.p[0])));
}

//点と線分の距離
double getDistanceSP(Line l,Point p){
	if(dot(calc_minus(l.p[1],l.p[0]),calc_minus(p,l.p[0])) < 0.0)return calc_len(calc_minus(p,l.p[0]));
	if(dot(calc_minus(l.p[0],l.p[1]),calc_minus(p,l.p[1])) < 0.0)return calc_len(calc_minus(p,l.p[1]));
	return getDistanceLP(l,p);
}

//線分と線分の距離
double getDistance(Line A,Line B){
	if(is_Cross(A,B))return 0.0;
	return min(min(getDistanceSP(A,B.p[0]),getDistanceSP(A,B.p[1])),
			min(getDistanceSP(B,A.p[0]),getDistanceSP(B,A.p[1])));
}

//交点を求める関数
Point calc_Cross_Point(double x1,double x2,double x3,double x4,double y1,double y2,double y3,double y4){
	Point ret;
	ret.x = ((x2-x1)*(y3*(x4-x3)+x3*(y3-y4))-(x4-x3)*(y1*(x2-x1)+x1*(y1-y2)))/((y2-y1)*(x4-x3)-(y4-y3)*(x2-x1));
	if(fabs(x1-x2) > EPS){
		ret.y = ((y2-y1)*ret.x+y1*(x2-x1)+x1*(y1-y2))/(x2-x1);
	}else{
		ret.y = ((y4-y3)*ret.x+y3*(x4-x3)+x3*(y3-y4))/(x4-x3);
	}
	return ret;
}

//インタフェース関数
Point calc_Cross_Point(Point a,Point b,Point c,Point d){
	return calc_Cross_Point(a.x,b.x,c.x,d.x,a.y,b.y,c.y,d.y);
}

Point calc_Cross_Point(Line A,Line B){

	if(getDistanceSP(B,A.p[0]) < EPS){

		return A.p[0];

	}else if(getDistanceSP(B,A.p[1]) < EPS){

		return A.p[1];

	}else if(getDistanceSP(A,B.p[0]) < EPS){

		return B.p[0];

	}else if(getDistanceSP(A,B.p[1]) < EPS){

		return B.p[1];
	}

	return calc_Cross_Point(A.p[0],A.p[1],B.p[0],B.p[1]);
}

double calc_S(Polygon g){

	int N = g.size();
	double ret = 0;

	for(int i = 0; i < g.size(); i++){
		ret += cross(g[i],g[(i+1)%N]);
	}
	return ret/2.0;
}

double calc_bottomS(Polygon P,Line line){

	int count = 0;
	int N = P.size();

	int index_1 = -1,index_2;
	Point cross1,cross2;

	for(int i = 0; i < N; i++){

		Line tmp_line = Line(P[i],P[(i+1)%N]);
		if(is_Cross(tmp_line,line)){
			//printf("線%dで交差\n",i);
			count++;
			if(index_1 == -1){

				index_1 = i;
				cross1 = calc_Cross_Point(tmp_line,line);
				//cross1.debug();

			}else{

				index_2 = i;
				cross2 =calc_Cross_Point(tmp_line,line);
				//cross2.debug();
			}
		}
	}

	if(count <= 1)return 0;

	Polygon A;
	for(int i = 0; i <= index_1; i++){

		A.push_back(P[i]);
	}
	A.push_back(cross1);
	A.push_back(cross2);

	for(int i = index_2+1; i < N; i++){

		A.push_back(P[i]);
	}

	return calc_S(A);
}

void func(){

	Polygon P;

	double x,y;
	for(int i = 0; i < N; i++){

		scanf("%lf %lf",&x,&y);

		P.push_back(Point(x,y));
	}

	for(int i = 0; i <= N-1; i++){

		Vector vec1 = P[(i-1+N)%N]-P[i];
		Vector vec2 = P[(i+1)%N]-P[i];

		RAD[i] = M_PI-acos(dot(vec1,vec2)/(abs(vec1)*abs(vec2)));
		//printf("RAD[%d]:%.3lf\n",i,RAD[i]);
	}

	double ans = 0;

	Polygon work;

	for(int i = 0; i <= N-1; i++){
	//for(int i = 1; i <= 1; i++){

		//printf("\n\n★★★i:%d\n",i);

		double tmp_dist = calc_dist(P[i],P[(i+1)%N]);
		work.clear();

		work.push_back(Point(0,0)); //P[i]を(0,0)、P[(i+1)%N]を(tmp_dist,0)にする
		work.push_back(Point(tmp_dist,0));

		Point pre = work[1];
		double rad = 0;

		double L = 0,R = 0;

		for(int k = 0; k < N-2; k++){

			double tmp_dist = calc_dist(P[(i+1+k)%N],P[(i+2+k)%N]);
			//printf("k:%d tmp_dist:%.3lf\n",k,tmp_dist);

			rad += RAD[(i+1+k)%N];
			//printf("rad:%.3lf\n",rad);
			Vector tmp = Vector(tmp_dist*cos(rad),tmp_dist*sin(rad));

			//printf("cos:%.3lf sin:%.3lf\n",tmp_dist*cos(rad),tmp_dist*sin(rad));

			Point next = pre+tmp;

			L = min(L,next.y);
			R = max(R,next.y);

			work.push_back(next);
			pre = next;
		}

	/*	printf("\nwork");
		for(int a = 0; a < work.size(); a++){

			work[a].debug();
		}


		printf("\nL:%.3lf R:%.3lf\n",L,R);*/

		//Line dog = Line(Point(-NUM,1.0),Point(NUM,1.0));
		//printf("想定開 %.3lf\n",calc_bottomS(work,dog));

		//continue;

		for(int loop = 0; loop < 100; loop++){

			double mid1 = (2.0*L+R)/3.0;
			double mid2 = (1.0*L+2.0*R)/3.0;

			Line tmp_line1 = Line(Point(-NUM,mid1),Point(NUM,mid1));
			Line tmp_line2 = Line(Point(-NUM,mid2),Point(NUM,mid2));

			double V1 = calc_bottomS(work,tmp_line1)*D;
			double V2 = calc_bottomS(work,tmp_line2)*D;

			if(fabs(V-V1) < fabs(V-V2)){

				R = mid2;

			}else{

				L = mid1;
			}
		}
		//printf("L:%.3lf R:%.3lf\n",L,R);
		ans = max(ans,(L+R)/2);
	}

	printf("%.10lf\n",ans);
}

int main(){

	while(true){

		scanf("%d %lf %lf",&N,&D,&V);
		if(N == 0)break;

		func();
	}

	return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 3640
final_rank: 19

code_snippet: #include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <numeric>
#include <bitset>
#include <cmath>

static const int MOD = 1000000007;
using ll = long long;
using u32 = unsigned;
using u64 = unsigned long long;
using namespace std;

template<class T> constexpr T INF = ::numeric_limits<T>::max()/32*15+208;

using real = double;
static constexpr real EPS = 1e-10;
struct Point {
    real x, y;
    Point& operator+=(const Point a) { x += a.x; y += a.y;  return *this; }
    Point& operator-=(const Point a) { x -= a.x; y -= a.y;  return *this; }
    Point& operator*=(const real k) { x *= k; y *= k;  return *this; }
    Point& operator/=(const real k) { x /= k; y /= k;  return *this; }
    Point operator+(const Point a) const {return Point(*this) += a; }
    Point operator-(const Point a) const {return Point(*this) -= a; }
    Point operator*(const real k) const {return Point(*this) *= k; }
    Point operator/(const real k) const {return Point(*this) /= k; }
    bool operator<(const Point &a) const { return (x != a.x ? x < a.x : y < a.y); }
    explicit Point(real a = 0, real b = 0) : x(a), y(b) {};
};

bool sorty(Point a, Point b){
    return (a.y != b.y ? a.y < b.y : a.x < b.x);
}

istream& operator>> (istream& s, Point& P){
    s >> P.x >> P.y;
    return s;
}

inline real dot(Point a, Point b){ return a.x*b.x + a.y*b.y; }
inline real cross(Point a, Point b){ return a.x*b.y - a.y*b.x; }
inline real abs(Point a){ return sqrt(dot(a, a)); }


real angle(Point A, Point B){
    return acos(dot(A, B)/abs(A)/abs(B));
}



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

int ccw(Point a, Point b, Point c){
    b -= a; c -= a;
    if(cross(b, c) > EPS) return COUNTER_CLOCKWISE;
    if(cross(b, c) < -EPS) return CLOCKWISE;
    if(dot(b, c) < 0) return ONLINE_BACK;
    if(abs(b) < abs(c)) return ONLINE_FRONT;
    return ON_SEGMENT;
}
struct Segment {
    Point a, b;
    Segment(Point x, Point y) : a(x), b(y) {};
};

struct Line {
    Point a, b;
    Line(Point x, Point y) : a(x), b(y) {};
};

struct Circle{
    Point c; real r;
    Circle(Point c, real r): c(c), r(r) {};
};

using Polygon = vector<Point>;

bool intersect(Segment s, Segment 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 intersect(Segment s, Line t){
    int a = ccw(t.a, t.b, s.a), b = ccw(t.a, t.b, s.b);
    return (!(a&1) || !(b&1) || a != b);
}

Point polar(double r, double t){
    return Point(r*cos(t), r*sin(t));
}

double arg(Point p){
    return atan2(p.y, p.x);
}

static constexpr int CONTAIN = 0;
static constexpr int INSCRIBE = 1;
static constexpr int INTERSECT = 2;
static constexpr int CIRCUMSCRIBED = 3;
static constexpr int SEPARATE = 4;

int intersect(Circle c1, Circle c2){
    if(c1.r < c2.r) swap(c1, c2);
    real d = abs(c1.c-c2.c);
    real r = c1.r + c2.r;
    if(fabs(d-r) < EPS) return CIRCUMSCRIBED;
    if(d > r) return SEPARATE;
    if(fabs(d+c2.r-c1.r) < EPS) return INSCRIBE;
    if(d+c2.r < c1.r) return CONTAIN;
    return INTERSECT;
}

real distance(Line l, Point c){
    return abs(cross(l.b-l.a, c-l.a)/abs(l.b-l.a));
}


real distance(Segment s, Point c){
    if(dot(s.b-s.a, c-s.a) < EPS) return abs(c-s.a);
    if(dot(s.a-s.b, c-s.b) < EPS) return abs(c-s.b);
    return abs(cross(s.b-s.a, c-s.a)) / abs(s.a-s.b);
}

real distance(Segment s, Segment t){
    if(intersect(s, t)) return 0.0;
    return min({distance(s, t.a), distance(s, t.b),
                distance(t, s.a), distance(t, s.b)});
}


Point project(Line l, Point p){
    Point Q = l.b-l.a;
    return l.a + Q*(dot(p-l.a, Q) / dot(Q, Q));
}


Point project(Segment s, Point p){
    Point Q = s.b-s.a;
    return s.a + Q*(dot(p-s.a, Q) / dot(Q, Q));
}

Point refrect(Segment s, Point p){
    Point Q = project(s, p);
    return Q*2-p;
}

bool isOrthogonal(Segment s, Segment t){
    return fabs(dot(s.b-s.a, t.b-t.a)) < EPS;
}

bool isparallel(Segment s, Segment t){
    return fabs(cross(s.b-s.a, t.b-t.a)) < EPS;
}


Point crossPoint(Segment s, Segment t){
    real d1 = cross(s.b-s.a, t.b-t.a);
    real d2 = cross(s.b-s.a, s.b-t.a);
    if(fabs(d1) < EPS && fabs(d2) < EPS) return t.a;
    return t.a+(t.b-t.a)*d2/d1;
}

Point crossPoint(Line s, Line t){
    real d1 = cross(s.b-s.a, t.b-t.a);
    real d2 = cross(s.b-s.a, s.b-t.a);
    if(fabs(d1) < EPS && fabs(d2) < EPS) return t.a;
    return t.a+(t.b-t.a)*d2/d1;
}

Polygon crossPoint(Circle c, Line l){
    Point p = project(l, c.c), q = (l.b-l.a)/abs(l.b-l.a);
    if(abs(distance(l, c.c)-c.r) < EPS){
        return {p};
    }
    double k = sqrt(c.r*c.r-dot(p-c.c, p-c.c));
    return {p-q*k, p+q*k};
}

Polygon crossPoint(Circle c, Segment s){
    auto tmp = crossPoint(c, Line(s.a, s.b));
    Polygon ret;
    for (auto &&i : tmp) {
        if(distance(s, i) < EPS) ret.emplace_back(i);
    }
    return ret;
}


Polygon crossPoint(Circle c1, Circle c2){
    double d = abs(c1.c-c2.c);
    double a = acos((c1.r*c1.r+d*d-c2.r*c2.r)/(2*c1.r*d));
    double t = arg(c2.c-c1.c);
    return {c1.c+polar(c1.r, t+a), c1.c+polar(c1.r, t-a)};
}

Polygon tangent(Circle c1, Point p){
    Circle c2 = Circle(p, sqrt(dot(c1.c-p, c1.c-p)-c1.r*c1.r));
    return crossPoint(c1, c2);
}
vector<Line> tangent(Circle c1, Circle c2){
    vector<Line> ret;
    if(c1.r < c2.r) swap(c1, c2);
    double k = dot(c1.c-c2.c, c1.c-c2.c);
    if(abs(k) < EPS) return {};
    Point u = (c2.c-c1.c)/sqrt(k);
    Point v(-u.y, u.x);
    for (auto &&i : {-1, 1}) {
        double h = (c1.r+i*c2.r)/sqrt(k);
        if(abs(h*h-1) < EPS){
            ret.emplace_back(c1.c+u*c1.r, c1.c+(u+v)*c1.r);
        }else if(h*h < 1){
            Point u2 = u*h, v2 = v*sqrt(1-h*h);
            ret.emplace_back(c1.c+(u2+v2)*c1.r, c2.c-(u2+v2)*c2.r*i);
            ret.emplace_back(c1.c+(u2-v2)*c1.r, c2.c-(u2-v2)*c2.r*i);
        }
    }
    return ret;
}

real area(Polygon v){
    if(v.size() < 3) return 0.0;
    real ans = 0.0;
    for (int i = 0; i < v.size(); ++i) {
        ans += cross(v[i], v[(i+1)%v.size()]);
    }
    return ans/2;
}

real area(Circle c, Polygon &v){
    int n = v.size();
    real ans = 0.0;
    Polygon u;
    for (int i = 0; i < n; ++i) {
        u.emplace_back(v[i]);
        auto q = crossPoint(c, Segment(v[i], v[(i+1)%n]));
        for (auto &&j : q) {
            u.emplace_back(j);
        }
    }
    for (int i = 0; i < u.size(); ++i) {
        Point A = u[i]-c.c, B = u[(i+1)%u.size()]-c.c;
        if(abs(A) >= c.r+EPS || abs(B) >= c.r+EPS){
            Point C = polar(1, arg(B)-arg(A));
            ans += c.r*c.r*arg(C)/2;
        }else {
            ans += cross(A, B)/2;
        }
    }
    return ans;
}

Polygon convex_hull(Polygon v){
    int n = v.size();
    sort(v.begin(),v.end(), sorty);
    int k = 0;
    Polygon ret(n*2);
    for (int i = 0; i < n; ++i) {
        while(k > 1 && cross(ret[k-1]-ret[k-2], v[i]-ret[k-1]) < 0) k--;
        ret[k++] = v[i];
    }
    for(int i = n-2, t=k; i >= 0; i--){
        while(k > t && cross(ret[k-1]-ret[k-2], v[i]-ret[k-1]) < 0) k--;
        ret[k++] = v[i];
    }
    ret.resize(k-1);
    return ret;
}

bool isconvex(Polygon v){
    int n = v.size();
    for (int i = 0; i < n; ++i) {
        if(ccw(v[(i+n-1)%n], v[i], v[(i+1)%n]) == CLOCKWISE) return false;
    }
    return true;
}

int contains(Polygon v, Point p){
    int n = v.size();
    bool x = false;
    static constexpr int IN = 2;
    static constexpr int ON = 1;
    static constexpr int OUT = 0;
    for (int i = 0; i < n; ++i) {
        Point a = v[i]-p, b = v[(i+1)%n]-p;
        if(fabs(cross(a, b)) < EPS && dot(a, b) < EPS) return ON;
        if(a.y > b.y) swap(a, b);
        if(a.y < EPS && EPS < b.y && cross(a, b) > EPS) x = !x;
    }
    return (x?IN:OUT);
}

real diameter(Polygon v){
    int n = v.size();
    if(n == 2) return abs(v[0]-v[1]);
    int i = 0, j = 0;
    for (int k = 0; k < n; ++k) {
        if(v[i] < v[k]) i = k;
        if(!(v[j] < v[k])) j = k;
    }
    real ret = 0;
    int si = i, sj = j;
    while(i != sj || j != si){
        ret = max(ret, abs(v[i]-v[j]));
        if(cross(v[(i+1)%n]-v[i], v[(j+1)%n]-v[j]) < 0.0) i = (i+1)%n;
        else j = (j+1)%n;
    }
    return ret;
}

Polygon convexCut(Polygon v, Line l){
    Polygon q;
    int n = v.size();
    for (int i = 0; i < n; ++i) {
        Point a = v[i], b = v[(i+1)%n];
        if(ccw(l.a, l.b, a) != -1) q.push_back(a);
        if(ccw(l.a, l.b, a)*ccw(l.a, l.b, b) < 0){
            q.push_back(crossPoint(Line(a, b), l));
        }
    }
    return q;
}

real closest_pair(Polygon &v, int l = 0, int r = -1){
    if(!(~r)){
        r = v.size();
        sort(v.begin(),v.end());
    }
    if(r - l < 2) {
        return abs(v.front()-v.back());
    }
    int mid = (l+r)/2;
    real p = v[mid].x;
    real d = min(closest_pair(v, l, mid), closest_pair(v, mid, r));
    inplace_merge(v.begin()+l, v.begin()+mid, v.begin()+r, sorty);
    Polygon u;
    for (int i = l; i < r; ++i) {
        if(fabs(v[i].x-p) >= d) continue;
        for (int j = 0; j < u.size(); ++j) {
            real dy = v[i].y-next(u.rbegin(), j)->y;
            if(dy >= d) break;
            d = min(d, abs(v[i]-*next(u.rbegin(), j)));
        }
        u.emplace_back(v[i]);
    }
    return d;
}

void solve(int n, int d, int v){
    Polygon p(n);
    for (auto &&i : p) cin >> i;
    vector<Segment> S;
    for (int i = 0; i < n; ++i) {
        S.emplace_back(p[i], p[(i+1)%n]);
    }
    double ans = 0;
    for (int i = 0; i < n; ++i) {
        Point A(-(p[(i+1)%n]-p[i]).y, (p[(i+1)%n]-p[i]).x);
        A /= abs(A);
        double ok = 0, ng = 3000;
        for (int j = 0; j < 100; ++j) {
            double mid = (ok+ng)/2;
            Line x(p[(i+1)%n]+A*mid, p[i]+A*mid);
            int good = 0;
            for (int k = 0; k < n; ++k) {
                if(intersect(S[k], x)) good = 1;
            }
            if(!good){
                ng = mid;
                continue;
            }
            if(area(convexCut(p, x))*d <= v) ok = mid;
            else ng = mid;
        }
        ans = max(ans, ok);
    }
    printf("%.10lf\n", ans);
}


int main() {
    int n, d, v;
    while(cin >> n >> d >> v, n){
        solve(n, d, v);
    }
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3232
final_rank: 8

code_snippet: #include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <deque>
#include <list>
#include <queue>
#include <stack>
#include <vector>
#include <utility>
#include <algorithm>
#include <map>
#include <set>
#include <complex>
#include <cmath>
#include <limits>
#include <cfloat>
#include <climits>
#include <ctime>
#include <cassert>
#include <numeric>
#include <functional>
#include <bitset>


using namespace std;
using Real = double;
using Point = complex<Real>;
const Real EPS = 1e-8, PI = acos(-1);

inline bool eq(double a, double b){ return fabs(b - a) < EPS; }

namespace std{
    bool operator<(const Point &a, const Point &b){
        return !eq(a.real(), b.real()) ? a.real() < b.real() : a.imag() < b.imag();
    }
}

struct Line{

    Point a, b;
    Line(Point a, Point b) : a(a), b(b){}
};

using Points = vector<Point>;
using Polygon = vector<Point>;

Real cross(const Point &a, const Point &b){
    return real(a) * imag(b) - imag(a) * real(b);
}

Real dot(const Point &a, const Point &b){
    return real(a) * real(b) + imag(a) * imag(b);
}

Point rotate(double theta, const Point &p){
    return Point(cos(theta) * p.real() - sin(theta) * p.imag(), sin(theta) * p.real() + cos(theta) * p.imag());
}

int ccw(const Point &a, Point b, Point c) {
  b = b - a, c = c - a;
  if(cross(b, c) > EPS) return +1;  
  if(cross(b, c) < -EPS) return -1; 
  if(dot(b, c) < 0) return +2;      
  if(norm(b) < norm(c)) return -2;  
  return 0;                         
}

Point crosspoint(const Line &l, const Line &m) {
  Real A = cross(l.b - l.a, m.b - m.a);
  Real B = cross(l.b - l.a, l.b - m.a);
  if(eq(abs(A), 0.0) && eq(abs(B), 0.0)) return m.a;
  return m.a + (m.b - m.a) * B / A;
}

Polygon convex_cut(const Polygon &U, Line l) {
  Polygon ret;
  for(int i = 0; i < U.size(); i++) {
    Point now = U[i], nxt = U[(i + 1) % U.size()];
    if(ccw(l.a, l.b, now) != -1) ret.push_back(now);
    if(ccw(l.a, l.b, now) * ccw(l.a, l.b, nxt) < 0) {
      ret.push_back(crosspoint(Line(now, nxt), l));
    }
  }
  return (ret);
}


Real area2(const Polygon &p) {
  Real A = 0;
  for(int i = 0; i < p.size(); ++i) {
    A += cross(p[i], p[(i + 1) % p.size()]);
  }
  return A;
}



signed main(){
        
    while(1){
        int n, d, v; cin >> n >> d >> v;
        if(n == 0) break;

        Polygon poly(n);
        for(int i = 0; i < n; i++){
            double x, y; cin >> x >> y;
            poly[i] = Point(x, y);

        }
        
        //cout << area2(poly) << endl;

        double ans = 0.0;
        for(int i = 0; i < n; i++){
            Point a = poly[i];
            Point b = poly[(i + 1) % n];
            double theta = PI / 2.0;
            Point pp = rotate(theta, b - a);
            pp = pp / abs(pp);


            double lb = 0.0;
            double ub = 1e9;
            for(int itr = 0; itr < 100; itr++){

                double h = (lb + ub) / 2.0;
                Line l = Line(b + h * pp, a + h * pp);

                auto tmp = convex_cut(poly, l);
                double Sum = abs(area2(convex_cut(poly, l)) / 2.0);
                //cout << Sum << endl;
                if(Sum * d < v) lb = h;
                else ub = h;
            }

            ans = max(ans, lb);
        }
        printf("%.10f\n", ans);
    }
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3660
final_rank: 15

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);
}




/* 多角形 */

typedef vector<Point> Polygon;



// 面積
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;
		ld D,V;cin>>D>>V;
		ld S=V/D;

		Polygon poly(N);
		for (int i = 0; i < N; ++i) {
			int x,y;cin>>x>>y;
			poly[i]=Point(x,y);
		}

		ld ans=0;
		for (int i = 0; i < N; ++i) {
			Line l(poly[i],poly[(i+1)%N]);

			Line bis=point_bisection(l.a,l.b);
			Point vec(bis.b-bis.a);

			vec/=abs(vec);

			ld amin=0;
			ld amax=1e6;
			int num=100;
			while (num--) {
				ld amid(amin/2+amax/2);
				Polygon cut_poly=convex_cut(poly,Line(l.a+vec*amid,l.b+vec*amid))[1];

				ld ar=get_area(cut_poly);

				if(ar<S)amin=amid;
				else amax=amid;
			}
			ans=max(ans,amin);
		}
		cout<<setprecision(10)<<fixed<<ans<<endl;

	}
	return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 3348
final_rank: 20

code_snippet: #include<bits/stdc++.h>
#define rep(i,n) for(int i=0;i<(int)n;i++)
#define all(c) (c).begin(),(c).end()
#define pb push_back
#define dbg(...) do{cerr<<__LINE__<<": ";dbgprint(#__VA_ARGS__, __VA_ARGS__);}while(0);

using namespace std;

namespace std{template<class S,class T>struct hash<pair<S,T>>{size_t operator()(const pair<S,T>&p)const{return ((size_t)1e9+7)*hash<S>()(p.first)+hash<T>()(p.second);}};template<class T>struct hash<vector<T>>{size_t operator()(const vector<T> &v)const{size_t h=0;for(auto i : v)h=h*((size_t)1e9+7)+hash<T>()(i)+1;return h;}};}
template<class T>ostream& operator<<(ostream &os, const vector<T> &v){os<<"[ ";rep(i,v.size())os<<v[i]<<(i==v.size()-1?" ]":", ");return os;}template<class T>ostream& operator<<(ostream &os,const set<T> &v){os<<"{ "; for(const auto &i:v)os<<i<<", ";return os<<"}";}
template<class T,class U>ostream& operator<<(ostream &os,const map<T,U> &v){os<<"{";for(const auto &i:v)os<<" "<<i.first<<": "<<i.second<<",";return os<<"}";}template<class T,class U>ostream& operator<<(ostream &os,const pair<T,U> &p){return os<<"("<<p.first<<", "<<p.second<<")";}
void dbgprint(const string &fmt){cerr<<endl;}template<class H,class... T>void dbgprint(const string &fmt,const H &h,const T&... r){cerr<<fmt.substr(0,fmt.find(","))<<"= "<<h<<" ";dbgprint(fmt.substr(fmt.find(",")+1),r...);}
typedef long long ll;typedef vector<int> vi;typedef pair<int,int> pi;
const double EPS = 1e-12, INF = 1e12, PI = acos(-1.0);
typedef complex<long double> P;
namespace std{
	bool operator<(const P& a, const P& b){
		return real(a) != real(b) ? real(a) < real(b) : imag(a) < imag(b);
	}
}
inline long double cross(const P& a, const P& b){ return imag(conj(a)*b); }
inline long 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);
	}
};
typedef vector<P> G;
inline int ccw(P a, P b, P c) {
	b -= a; c -= a;
	if(cross(b, c) >  EPS)   return +1;      // counter clockwise
	if(cross(b, c) < -EPS)   return -1;      // clockwise
	if(dot(b, c)   < -EPS)   return +2;      // c--a--b on line
	if(norm(b)+EPS <norm(c)) return -2;      // a--b--c on line
	return 0;                                   // c is between a and b (inclusive)
}
P crosspoint(const L &l, const L &m) {
	long double A = cross(l[1] - l[0], m[1] - m[0]);
	long double B = cross(l[1] - l[0], l[1] - m[0]);
	if (abs(A) < EPS && abs(B) < EPS) return m[0]; // same line
	if (abs(A) < EPS) assert(false); // !!!PRECONDITION NOT SATISFIED!!!
	return m[0] + B / A * (m[1] - m[0]);
}
#define curr(P, i) P[i]
#define next(P, i) P[(i+1)%P.size()]
long double area2(const G& g) {
	long double A = 0;
	for (int i = 0; i < g.size(); ++i) 
		A += cross(curr(g, i), next(g, i));
	return A;
}
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;
}
int main(){
	cin.tie(0); cin.sync_with_stdio(0);
	int n, d, v;
	while(cin >> n >> d >> v, n){
		G g;
		long double ans = 0;
		rep(i, n){ int x, y; cin >> x >> y; g.emplace_back(x, y); }
		rep(i, n){
			long double lo = 0, hi = 4000, mid;
			rep(it, 100){
				mid = (lo + hi) / 2;
				L l(g[(i + 1) % n], g[i]);
				P p = (l[0] - l[1]) * P(0, mid / abs(l[0] - l[1]));
				l[0] += p;
				l[1] += p;
				G h = convex_cut(g, l);
				if(area2(h) * d / 2 >= v - EPS) hi = mid;
				else lo = mid;
			}
			ans = max(ans, lo);
		}
		printf("%.20f\n", (double)ans);
	}
	return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 3252
final_rank: 17

code_snippet: #include <bits/stdc++.h>
#define x real()
#define y imag()
using namespace std;
typedef complex<double> point;

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;
}
int ccw(point a, point b, point c) {
	point d = b - a, e = c - a;
	if (cross(d, e) > 0)
		return 1; //"COUNTER_CLOCKWISE"
	if (cross(d, e) < 0)
		return -1; //"CLOCKWISE"
	if (dot(d, e) < 0)
		return 2; //"ONLINE_BACK"
	if (abs(d) < abs(e))
		return -2; //"ONLINE_FRONT"
	return 0; //"ON_SEGMENT"
}

point crosspoint(point a, point b, point c, point d) {
	a -= d;
	b -= d;
	c -= d;
	return d + a + (b - a) * imag(a / c) / imag(a / c - b / c);
}

vector<point> ConvexCut(vector<point> &polygon, point a, point b) {
	vector<point> res;
	for (int i = 0; i < polygon.size(); i++) {
		point A = polygon[i], B = polygon[(i + 1) % polygon.size()];
		if (ccw(a, b, A) != -1)
			res.push_back(A);
		if (ccw(a, b, A) * ccw(a, b, B) == -1)
			res.push_back(crosspoint(a, b, A, B));
	}
	return res;
}

double get_area(vector<point> polygon) {
	if (polygon.size() < 3)
		return 0;
	double res = 0;
	for (int i = 0; i < polygon.size(); i++)
		res += cross(polygon[i], polygon[(i + 1) % polygon.size()]) / 2;
	return res;
}

int main() {
	while (1) {
		int n, d;
		double V;
		vector<point> pl;
		cin >> n >> d >> V;
		if (!n && !d && !V)
			break;
		for (int i = 0, a, b; i < n; i++)
			cin >> a >> b, pl.push_back(point(a, b));
		V = min(get_area(pl) * d, V);

		double ans = 0;
		for (int i = 0; i < n; i++) {
			double L = 0, M, R = 2010;
			int I = 100;
			while (I--) {
				M = (L + R) / 2;
				point h = pl[(i + 1) % n] - pl[i], b = h;
				h = (point(0, M) * h / abs(h)) + pl[i];
				vector<point> a = ConvexCut(pl, h + b, h);
				if (get_area(a) * d >= V)
					R = M;
				else
					L = M + 0.00000001;
			}
			ans = max(ans, L);
		}
		printf("%.8f\n", ans);
	}
	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3268
final_rank: 9

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef complex<double> point;
typedef pair<point,point> line;
const double EPS=1e-8;

//テ・ツ??ァツゥツ?
double dot(point a,point b){
  return real(conj(a)*b);
}

//テ・ツ、ツ姪ァツゥツ?
double cross(point a,point b){
  return imag(conj(a)*b);
}

int ccw(point a,point b,point c){
  point d=b-a;
  point e=c-a;
  if(cross(d,e)>0)return 1;//テ・ツキツヲテ・ツ?エ
  if(cross(d,e)<0)return -1;//テ・ツ渉ウテ・ツ?エ
  if(dot(d,e)<0)return 2;//onlineback
  if(abs(d)<abs(e))return -2;//onlinefront
  return 0;//onsegment
}

point crosspoint_ll(line l1, line l2){
  double a=cross(l1.second-l1.first,l2.second-l2.first);
  double b=cross(l1.second-l1.first,l1.second-l2.first);
  if(fabs(a)<EPS&&fabs(b)<EPS)return l2.first;
  else if(fabs(a)>=EPS) return l2.first+b/a*(l2.second-l2.first);
}

vector<point> Convex_Cut(vector<point> polygon,line l){
  vector<point> res;
  for(int i=0;i<polygon.size();i++){
    point a=polygon[i],b=polygon[(i+1)%polygon.size()];
    if(ccw(l.first,l.second,a)!=-1)res.push_back(a);
    if(ccw(l.first,l.second,a)*ccw(l.first,l.second,b)<0)
      res.push_back(crosspoint_ll(line(a,b),l));
  }
  return res;
}

double get_area(vector<point> polygon){
  double res=0;
  for(int i=0;i<polygon.size();i++)
    res+=cross(polygon[i],polygon[(i+1)%polygon.size()]);
  return res/2;
}

int n,d,V,x,y;

double bynary_search(vector<point> polygon,point a,point b){
  b-=a;
  for(int i=0;i<n;i++)
    polygon[i]-=a,polygon[i]=polygon[i]*conj(b)/abs(b);
  double l=0,r=(1e9),m;
  while(l+EPS<r){
    m=(l+r)/2;
    point A=point(abs(b),m),B=point(0,m);
    if(get_area(Convex_Cut(polygon,line(A,B)))*d<V)l=m+EPS;
    else r=m;
  }
  return l;
}

int main(){
  vector<point> polygon;
  while(1){
    double ans=0;
    cin>>n>>d>>V;
    if(!n&&!d&&!V)break;
    for(int i=0;i<n;i++)
      cin>>x>>y,polygon.push_back(point(x,y));
    for(int i=0;i<n;i++){
      point a=polygon[i],b=polygon[(i+1)%n];
      ans=max(ans,bynary_search(polygon,a,b));
    }
    printf("%.9f\n",ans);
    polygon.clear();
  }
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 1248
final_rank: 1

code_snippet: #include <bits/stdc++.h>
  
using namespace std;
  
#define EPS 1e-9
  
struct Point {
    double x, y;
    Point() {}
    Point(double x, double y) : x(x), y(y){}
    
    Point operator + (const Point &p) const {
        return Point(x + p.x, y + p.y);
    }
    
    Point operator - (const Point &p) const {
        return Point(x - p.x, y - p.y);
    }
  
    Point operator * (const double k) const {
        return Point(x * k, y * k);
    }
  
    Point operator / (const double k) const {
        return Point(x / k, y / k);
    }
};
  
typedef Point Vector;
  
double dot(const Point &a, const Point &b)
{
    return a.x * b.x + a.y * b.y;
}
  
double cross(const Point &a, const Point &b)
{
    return a.x * b.y - b.x * a.y;
}
  
double norm(const Point &p)
{
    return dot(p, p);
}
  
double abs(const Point &p)
{
    return sqrt(norm(p));
}
  
struct Line {
    Point s, t;
    Line(){}
    Line(Point s, Point t) : s(s), t(t) {}
};
  
vector<Vector> normal_line_vector(const Line &l)
{
    vector<Vector> vs;
    Vector v = l.t - l.s, p = v / abs(v);
    vs.push_back(Point(-p.y, p.x));
    vs.push_back(Point(p.y, p.x));
    return vs;
}
  
vector<Line> translation(const Line &l, double d)
{
    vector<Vector> nlv = normal_line_vector(l);
    vector<Line> nl;
    nl.push_back(Line(l.t + nlv[0] * d, l.s + nlv[0] * d));
    nl.push_back(Line(l.t + nlv[1] * d, l.s + nlv[1] * d));
    return nl;
}
 
int ccw(const Point &p0, const Point &p1, const 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 crosspointLL(const Line &a, const Line &b)
{
    Vector va = a.t - a.s, vb = b.t - b.s;
    double d = cross(vb, va);
    if (abs(d) < EPS) return b.s;
    return a.s + va * cross(vb, b.t - a.s) * (1.0 / d);
}
  
typedef vector<Point> Polygon;
#define curr(G, i) (G[i%G.size()])
#define next(G, i) (G[(i+1)%G.size()])
  
Polygon convex_cut(const Polygon &pg, const Line &l)
{
    Polygon res;
    for (int i = 0; i < (int)pg.size(); i++) {
    Point cp = curr(pg,i), np = next(pg,i);
    if(ccw(l.s, l.t, cp) != -1) res.push_back(cp);
    if(ccw(l.s, l.t, cp) * ccw(l.s, l.t, np) < 0){
        res.push_back(crosspointLL(Line(cp, np), l));
    }
    }
    return res;
}
 
double area(const Polygon &pg)
{
    double res = 0;
    for (int i = 0; i < (int)pg.size(); i++) {
        res += cross(pg[i], next(pg, i));
    }
    return abs(res) / 2.0;
}
  
double calc(Polygon &pg, double d, Line &l, double V)
{
    double lb = 0, ub = 25252;
    for (int i = 0; i < 150; i++) {
        double h = (lb + ub) / 2;
        vector<Line> vl = translation(l, h);
        Line nl = (ccw(l.s, l.t, vl[0].s) == 1 ? vl[0] : vl[1]);       
        Polygon npg = convex_cut(pg, nl);
        double v = d * area(npg);
        if (v < V) {
            lb = h;
        } else {
            ub = h;
        }
    }
    return lb;
}
 
double solve(Polygon &pg, double d, double V)
{
    int n = pg.size();
    double max_height = 0;
    for (int i = 0; i < n; i++) {
        Line l(curr(pg, i), next(pg, i));
        max_height = max(max_height, calc(pg, d, l, V));
    }
    return max_height;
}
  
int main()
{
    int n;
    double d, V;
    while (cin >> n >> d >> V, n) {
        Polygon pg(n);
        for (int i = 0; i < n; i++) {
            cin >> pg[i].x >> pg[i].y;
        }
        printf("%.10f\n", solve(pg, d, V));
    }
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3216
final_rank: 7

code_snippet: #include <bits/stdc++.h>
#define x real()
#define y imag()
using namespace std;
typedef complex<double> point;

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;}
int ccw(point a,point b,point c){
  point d = b-a,e = c-a;
  if(cross(d,e)>0) return 1;//"COUNTER_CLOCKWISE"
  if(cross(d,e)<0) return -1;//"CLOCKWISE"
  if(dot(d,e)<0) return 2;//"ONLINE_BACK"
  if(abs(d) < abs(e)) return -2;//"ONLINE_FRONT"
  return 0;//"ON_SEGMENT"
}

point crosspoint(point a,point b,point c,point d){
  a-=d;b-=d;c-=d;
  return d+a+(b-a)*imag(a/c)/imag(a/c-b/c);
}

vector<point> ConvexCut(vector<point> &polygon,point a,point b){
  vector <point> res;
  for(int i=0;i<polygon.size();i++){
    point A=polygon[i],B=polygon[(i+1)%polygon.size()];
    if(ccw(a,b,A)!=-1)res.push_back(A);
    if(ccw(a,b,A)*ccw(a,b,B)==-1)res.push_back(crosspoint(a,b,A,B));
  }
  return res;
}

double get_area(vector <point> &polygon){
  if(polygon.size()<3)return 0;
  double res=0;
  for(int i=0;i<polygon.size();i++)
    res+=cross(polygon[i],polygon[(i+1)%polygon.size()])/2;
  return res;
}

int main(){
  while(1){
    int n,d;
    double V;
    vector <point> pl;
    cin>>n>>d>>V;
    if(!n&&!d&&!V) break;
    for(int i=0,a,b;i<n;i++) cin>>a>>b,pl.push_back(point(a,b));
    V=min(get_area(pl)*d,V);

    double ans=0;
    for(int i=0;i<n;i++){
      double L=0,M,R=2010;
      int I=100;
      while(I--){
	M=(L+R)/2;
	point h=pl[(i+1)%n]-pl[i],b=h;
	h=(point(0,M)*h/abs(h))+pl[i];
	vector<point> a=ConvexCut(pl,h+b,h);
	if(get_area(a)*d>=V)R=M;
	else L=M+0.00000001;
      }
      ans=max(ans,L);
    }
    printf("%.8f\n",ans);
  }
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 1276
final_rank: 2

code_snippet: #include <bits/stdc++.h>
#define x real()
#define y imag()
using namespace std;
typedef complex<double> point;

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;}
int ccw(point a,point b,point c){
  point d = b-a,e = c-a;
  if(cross(d,e)>0) return 1;//"COUNTER_CLOCKWISE"
  if(cross(d,e)<0) return -1;//"CLOCKWISE"
  if(dot(d,e)<0) return 2;//"ONLINE_BACK"
  if(abs(d) < abs(e)) return -2;//"ONLINE_FRONT"
  return 0;//"ON_SEGMENT"
}

point crosspoint(point a,point b,point c,point d){
  a-=d;b-=d;c-=d;
  return d+a+(b-a)*imag(a/c)/imag(a/c-b/c);
}

vector<point> ConvexCut(vector<point> &polygon,point a,point b){
  vector <point> res;
  for(int i=0;i<polygon.size();i++){
    point A=polygon[i],B=polygon[(i+1)%polygon.size()];
    if(ccw(a,b,A)!=-1)res.push_back(A);
    if(ccw(a,b,A)*ccw(a,b,B)==-1)res.push_back(crosspoint(a,b,A,B));
  }
  return res;
}

double get_area(vector <point> &polygon){
  if(polygon.size()<3)return 0;
  double res=0;
  for(int i=0;i<polygon.size();i++)
    res+=cross(polygon[i],polygon[(i+1)%polygon.size()])/2;
  return res;
}

int main(){
  while(1){
    int v,n,d;
    vector <point> pl;
    cin>>n>>d>>v;
    if(!n&&!d&&!v) break;
    for(int i=0,a,b;i<n;i++) cin>>a>>b,pl.push_back(point(a,b));
    double V=min(get_area(pl)*d,(double)v),ans=0;
    
    for(int i=0;i<n;i++){
      double L=0,M,R=2010;
      int I=1000;
      while(I--){
	M=(L+R)/2;
	point h=pl[(i+1)%n]-pl[i],b=h;
	h=(point(0,M)*h/abs(h))+pl[i];
	vector<point> a=ConvexCut(pl,h+b,h);
	if(get_area(a)*d>=V)R=M;
	else L=M+0.000000001;
      }
      ans=max(ans,L);
    }
    printf("%f\n",ans);
  }
  return 0;
}
accuracy: 1
time_ms: 130
memory_kb: 1244
final_rank: 11

code_snippet: #include <bits/stdc++.h>
#define x real()
#define y imag()
using namespace std;
typedef complex<double> point;

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;}
int ccw(point a,point b,point c){
  point d = b-a,e = c-a;
  if(cross(d,e)>0) return 1;//"COUNTER_CLOCKWISE"
  if(cross(d,e)<0) return -1;//"CLOCKWISE"
  if(dot(d,e)<0) return 2;//"ONLINE_BACK"
  if(abs(d) < abs(e)) return -2;//"ONLINE_FRONT"
  return 0;//"ON_SEGMENT"
}

point crosspoint(point a,point b,point c,point d){
  a-=d;b-=d;c-=d;
  return d+a+(b-a)*imag(a/c)/imag(a/c-b/c);
}

vector<point> ConvexCut(vector<point> &polygon,point a,point b){
  vector <point> res;
  for(int i=0;i<polygon.size();i++){
    point A=polygon[i],B=polygon[(i+1)%polygon.size()];
    if(ccw(a,b,A)!=-1)res.push_back(A);
    if(ccw(a,b,A)*ccw(a,b,B)==-1)res.push_back(crosspoint(a,b,A,B));
  }
  return res;
}

double get_area(vector <point> &polygon){
  if(polygon.size()<3)return 0;
  double res=0;
  for(int i=0;i<polygon.size();i++)
    res+=cross(polygon[i],polygon[(i+1)%polygon.size()])/2;
  return res;
}

int main(){
  while(1){
    int v,n,d;
    vector <point> pl;
    cin>>n>>d>>v;
    if(!n&&!d&&!v) break;
    for(int i=0,a,b;i<n;i++) cin>>a>>b,pl.push_back(point(a,b));
    
    double V=min(get_area(pl)*d,(double)v),ans=0;
    
    for(int i=0;i<n;i++){
      double L=0,M,R=2010;
      int I=1000;
      while(I--){
	M=(L+R)/2;
	point h=pl[(i+1)%n]-pl[i],b=h;
	h=(point(0,M)*h/abs(h))+pl[i];
	vector<point> a=ConvexCut(pl,h+b,h);
	if(get_area(a)*d>=V)R=M;
	else L=M+0.000000001;
      }
      ans=max(ans,L);
    }
    printf("%.8f\n",ans);
  }
  return 0;
}
accuracy: 1
time_ms: 140
memory_kb: 1252
final_rank: 16

code_snippet: #include <bits/stdc++.h>
#define x real()
#define y imag()
using namespace std;
typedef complex<double> point;

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;}
int ccw(point a,point b,point c){
  point d = b-a,e = c-a;
  if(cross(d,e)>0) return 1;//"COUNTER_CLOCKWISE"
  if(cross(d,e)<0) return -1;//"CLOCKWISE"
  if(dot(d,e)<0) return 2;//"ONLINE_BACK"
  if(abs(d) < abs(e)) return -2;//"ONLINE_FRONT"
  return 0;//"ON_SEGMENT"
}

point crosspoint(point a,point b,point c,point d){
  a-=d;b-=d;c-=d;
  return d+a+(b-a)*imag(a/c)/imag(a/c-b/c);
}

vector<point> ConvexCut(vector<point> &polygon,point a,point b){
  vector <point> res;
  for(int i=0;i<polygon.size();i++){
    point A=polygon[i],B=polygon[(i+1)%polygon.size()];
    if(ccw(a,b,A)!=-1)res.push_back(A);
    if(ccw(a,b,A)*ccw(a,b,B)==-1)res.push_back(crosspoint(a,b,A,B));
  }
  return res;
}

double get_area(vector <point> &polygon){
  if(polygon.size()<3)return 0;
  double res=0;
  for(int i=0;i<polygon.size();i++)
    res+=cross(polygon[i],polygon[(i+1)%polygon.size()])/2;
  return res;
}

int main(){
  while(1){
    int v,n,d;
    vector <point> pl;
    cin>>n>>d>>v;
    if(!n&&!d&&!v) break;
    for(int i=0,a,b;i<n;i++) cin>>a>>b,pl.push_back(point(a,b));
    
    double V=min(get_area(pl)*d,(double)v),ans=0;
    
    for(int i=0;i<n;i++){
      double L=0,M,R=2010;
      int I=1000;
      while(I--){
	M=(L+R)/2;
	point h=pl[(i+1)%n]-pl[i],b=h;
	h=(point(0,M)*h/abs(h))+pl[i];
	vector<point> a=ConvexCut(pl,h+b,h);
	double res=get_area(a);
	assert(res>0);
	if(res*d>=V)R=M;
	else L=M+0.000000001;
      }
      ans=max(ans,L);
    }
    printf("%.8f\n",ans);
  }
  return 0;
}
accuracy: 1
time_ms: 130
memory_kb: 1252
final_rank: 12

code_snippet: #include <bits/stdc++.h>
#define x real()
#define y imag()
#define EPS 0.0000001
using namespace std;
typedef complex<double> point;

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;}
int ccw(point a,point b,point c){
  point d = b-a,e = c-a;
  if(cross(d,e)>0) return 1;//"COUNTER_CLOCKWISE"
  if(cross(d,e)<0) return -1;//"CLOCKWISE"
  if(dot(d,e)<0) return 2;//"ONLINE_BACK"
  if(abs(d) < abs(e)) return -2;//"ONLINE_FRONT"
  return 0;//"ON_SEGMENT"
}

point crosspoint(point a,point b,point c,point d){
  a-=d;b-=d;c-=d;
  return d+a+(b-a)*imag(a/c)/imag(a/c-b/c);
}

vector<point> ConvexCut(vector<point> &polygon,point a,point b){
  vector <point> res;
  for(int i=0;i<polygon.size();i++){
    point A=polygon[i],B=polygon[(i+1)%polygon.size()];
    if(ccw(a,b,A)!=-1)res.push_back(A);
    if(ccw(a,b,A)*ccw(a,b,B)==-1)res.push_back(crosspoint(a,b,A,B));
  }
  return res;
}

double get_area(vector <point> &polygon){
  if(polygon.size()<3)return 0;
  double res=0;
  for(int i=0;i<polygon.size();i++)
    res+=cross(polygon[i],polygon[(i+1)%polygon.size()])/2;
  return res;
}

int main(){
  while(1){
    int v,n,d;
    vector <point> pl;
    cin>>n>>d>>v;
    if(!n&&!d&&!v) break;
    for(int i=0,a,b;i<n;i++) cin>>a>>b,pl.push_back(point(a,b));
    
    double V=min(get_area(pl)*d,(double)v),ans=0;

    for(int i=0;i<n;i++){
      double L=0,M,R=2010;
      int I=1000;
      while(I--){
	M=(L+R)/2;
	point h=pl[(i+1)%n]-pl[i],b=h;
	h=(point(0,M)*h/abs(h))+pl[i];

	if(ccw(pl[(i+1)%n],pl[i],h)*ccw(pl[(i+1)%n],pl[i],h+b)<=0)assert(0);
	vector<point> a=ConvexCut(pl,h+b,h);
	double res=get_area(a);
	assert(res>0);
	if(res*d>=V)R=M;
	else L=M+0.000000001;
      }
      ans=max(ans,L);
    }
    assert(ans<2001&&ans>0.0001);
    printf("%.8f\n",ans);
  }
  return 0;
}
accuracy: 1
time_ms: 130
memory_kb: 1252
final_rank: 12

code_snippet: #include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <complex>
#include <queue>
#include <deque>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <iomanip>
#include <assert.h>
#include <array>
#include <cstdio>
#include <cstring>
#include <random>
#include <functional>
#include <numeric>
#include <bitset>
#include <fstream>

using namespace std;

#define REP(i,a,b) for(int i=a;i<(int)b;i++)
#define rep(i,n) REP(i,0,n)
#define all(c) (c).begin(), (c).end()
#define zero(a) memset(a, 0, sizeof a)
#define minus(a) memset(a, -1, sizeof a)
template<class T1, class T2> inline bool minimize(T1 &a, T2 b) { return b < a && (a = b, 1); }
template<class T1, class T2> inline bool maximize(T1 &a, T2 b) { return a < b && (a = b, 1); }

typedef long long ll;
int const inf = 1<<29;

const double EPS = 1e-9;

using number = double;

struct point {
  number x, y;
  point operator + (point r) { return point{x + r.x, y + r.y}; }
  point operator + (const point& r) const { return point{x + r.x, y + r.y}; }
  point operator - (point r) { return point{x - r.x, y - r.y}; }
  point operator - (const point& r) const { return point{x - r.x, y - r.y}; }
  point operator * (point r) { return point{x*r.x - y*r.y, x*r.y + r.x*y}; }
  void operator -= (point r) { x -= r.x, y -= r.y; }
  point nml() { return point{x/sqrt(x*x+y*y), y/sqrt(x*x+y*y)}; }
};
point operator * (number k, point p) { return point{k * p.x, k * p.y}; }

struct line {
  point s, t;
};

typedef line segment;

number dot(point a, point b) {
  return a.x*b.x + a.y*b.y;
}

number cross(point a, point b) {
  return a.x*b.y - a.y*b.x;
}

number norm(point p) {
  return p.x * p.x + p.y * p.y;
}

struct polygon : public vector<point> {
  number area2() {
    number ret{};
    rep(i, this->size())
      ret += cross((*this)[i],(*this)[(i+1)%this->size()]);
    return abs(ret);
  }
};

int ccw(point a, point b, point c) {
  b -= a, c -= a;
  if(cross(b, c) > +EPS) return +1;
  if(cross(b, c) < -EPS) return -1;
  if(dot(b, c) < -EPS) return +2;
  if(norm(b) < norm(c)) return -2;
  return 0;
}

point crosspoint(const line &l, const line &m) {
  number A = cross(l.t - l.s, m.t - m.s);
  number B = cross(l.t - l.s, l.t - m.s);
  if(abs(A) < EPS && abs(B) < EPS) return m.s; // same line
  if(abs(A) < EPS) assert(false); // !!!PRECONDITION NOT SATISFIED!!!
  return m.s + B / A * (m.t - m.s);
}

polygon convex_cut(polygon& g, line& l) {
  polygon ret{};
  rep(i, g.size()) {
    auto a = g[i], b = g[(i+1)%g.size()];
    if(ccw(l.s, l.t, a) != -1) ret.push_back(a);
    if(ccw(l.s, l.t, a) * ccw(l.s, l.t, b) < 0)
      ret.push_back(crosspoint(line{a, b}, l));
  }
  return ret;
}

bool compare(polygon& g, number V, number D, int ridx, number height) {
  line l{g[(ridx+1)%g.size()], g[ridx]};
  point v = height * ((l.t - l.s) * point{0, -1}).nml();
  l.s = l.s + v, l.t = l.t + v;
  return convex_cut(g, l).area2() * D < V * 2;
}

int main() {
  int N; number D, V;
  while(cin >> N >> D >> V && (N||D||V)) {
    polygon g{};
    rep(i, N) {
      number x, y; cin >> x >> y;
      g.push_back(point{x, y});
    }

    number ans = 0;

    rep(i, N) {
      number l = 0, h = 114514;
      rep(_, 100) {
        number mid = (l + h) / 2;
        (compare(g, V, D, i, mid) ? l : h) = mid;
      }
      ans = max(ans, l);
    }

    printf("%.10f\n", ans);
  }
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3208
final_rank: 6

code_snippet: #include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <complex>
#include <queue>
#include <deque>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <iomanip>
#include <assert.h>
#include <array>
#include <cstdio>
#include <cstring>
#include <random>
#include <functional>
#include <numeric>
#include <bitset>
#include <fstream>

using namespace std;

#define REP(i,a,b) for(int i=a;i<(int)b;i++)
#define rep(i,n) REP(i,0,n)
#define all(c) (c).begin(), (c).end()
#define zero(a) memset(a, 0, sizeof a)
#define minus(a) memset(a, -1, sizeof a)
template<class T1, class T2> inline bool minimize(T1 &a, T2 b) { return b < a && (a = b, 1); }
template<class T1, class T2> inline bool maximize(T1 &a, T2 b) { return a < b && (a = b, 1); }

typedef long long ll;
int const inf = 1<<29;

const double EPS = 1e-9;

using number = double;

struct point {
  number x, y;
  point operator + (point r) { return point{x + r.x, y + r.y}; }
  point operator + (const point& r) const { return point{x + r.x, y + r.y}; }
  point operator - (point r) { return point{x - r.x, y - r.y}; }
  point operator - (const point& r) const { return point{x - r.x, y - r.y}; }
  point operator * (point r) { return point{x*r.x - y*r.y, x*r.y + r.x*y}; }
  void operator -= (point r) { x -= r.x, y -= r.y; }
  point nml() { return point{x/sqrt(x*x+y*y), y/sqrt(x*x+y*y)}; }
};
point operator * (number k, point p) { return point{k * p.x, k * p.y}; }

struct line {
  point s, t;
};

typedef line segment;

number dot(point a, point b) {
  return a.x*b.x + a.y*b.y;
}

number cross(point a, point b) {
  return a.x*b.y - a.y*b.x;
}

number norm(point p) {
  return p.x * p.x + p.y * p.y;
}

struct polygon : public vector<point> {
  number area2() {
    number ret{};
    rep(i, this->size())
      ret += cross((*this)[i],(*this)[(i+1)%this->size()]);
    return abs(ret);
  }
};

int ccw(point a, point b, point c) {
  b -= a, c -= a;
  if(cross(b, c) > +EPS) return +1;
  if(cross(b, c) < -EPS) return -1;
  if(dot(b, c) < -EPS) return +2;
  if(norm(b) < norm(c)) return -2;
  return 0;
}

point crosspoint(const line &l, const line &m) {
  number A = cross(l.t - l.s, m.t - m.s);
  number B = cross(l.t - l.s, l.t - m.s);
  if(abs(A) < EPS && abs(B) < EPS) return m.s; // same line
  if(abs(A) < EPS) assert(false); // !!!PRECONDITION NOT SATISFIED!!!
  return m.s + B / A * (m.t - m.s);
}

polygon convex_cut(polygon& g, line& l) {
  polygon ret{};
  rep(i, g.size()) {
    auto a = g[i], b = g[(i+1)%g.size()];
    if(ccw(l.s, l.t, a) != -1) ret.push_back(a);
    if(ccw(l.s, l.t, a) * ccw(l.s, l.t, b) < 0)
      ret.push_back(crosspoint(line{a, b}, l));
  }
  return ret;
}

bool compare(polygon& g, number V, number D, int ridx, number height) {
  line l{g[(ridx+1)%g.size()], g[ridx]};
  point v = height * ((l.t - l.s) * point{0, -1}).nml();
  l.s = l.s + v, l.t = l.t + v;
  return convex_cut(g, l).area2() * D < V * 2;
}

int main() {
  int N; number D, V;
  while(cin >> N >> D >> V && (N||D||V)) {
    polygon g{};
    rep(i, N) {
      number x, y; cin >> x >> y;
      g.push_back(point{x, y});
    }

    number ans = 0;

    rep(i, N) {
      number l = 0, h = 114514;
      rep(_, 300) {
        number mid = (l + h) / 2;
        (compare(g, V, D, i, mid) ? l : h) = mid;
      }
      ans = max(ans, l);
    }

    printf("%.10f\n", ans);
  }
  return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 3284
final_rank: 14

code_snippet: #include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <complex>
#include <queue>
#include <deque>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <iomanip>
#include <assert.h>
#include <array>
#include <cstdio>
#include <cstring>
#include <random>
#include <functional>
#include <numeric>
#include <bitset>
#include <fstream>

using namespace std;

#define REP(i,a,b) for(int i=a;i<(int)b;i++)
#define rep(i,n) REP(i,0,n)
#define all(c) (c).begin(), (c).end()
#define zero(a) memset(a, 0, sizeof a)
#define minus(a) memset(a, -1, sizeof a)
template<class T1, class T2> inline bool minimize(T1 &a, T2 b) { return b < a && (a = b, 1); }
template<class T1, class T2> inline bool maximize(T1 &a, T2 b) { return a < b && (a = b, 1); }

typedef long long ll;
int const inf = 1<<29;

const double EPS = 1e-9;

using number = double;

struct point {
  number x, y;
  point operator + (point r) { return point{x + r.x, y + r.y}; }
  point operator + (const point& r) const { return point{x + r.x, y + r.y}; }
  point operator - (point r) { return point{x - r.x, y - r.y}; }
  point operator - (const point& r) const { return point{x - r.x, y - r.y}; }
  point operator * (point r) { return point{x*r.x - y*r.y, x*r.y + r.x*y}; }
  void operator -= (point r) { x -= r.x, y -= r.y; }
  point nml() { return point{x/sqrt(x*x+y*y), y/sqrt(x*x+y*y)}; }
};
point operator * (number k, point p) { return point{k * p.x, k * p.y}; }

struct line {
  point s, t;
};

typedef line segment;

number dot(point a, point b) {
  return a.x*b.x + a.y*b.y;
}

number cross(point a, point b) {
  return a.x*b.y - a.y*b.x;
}

number norm(point p) {
  return p.x * p.x + p.y * p.y;
}

struct polygon : public vector<point> {
  number area2() {
    number ret{};
    rep(i, this->size())
      ret += cross((*this)[i],(*this)[(i+1)%this->size()]);
    return abs(ret);
  }
};

int ccw(point a, point b, point c) {
  b -= a, c -= a;
  if(cross(b, c) > +EPS) return +1;
  if(cross(b, c) < -EPS) return -1;
  if(dot(b, c) < -EPS) return +2;
  if(norm(b) < norm(c)) return -2;
  return 0;
}

point crosspoint(const line &l, const line &m) {
  number A = cross(l.t - l.s, m.t - m.s);
  number B = cross(l.t - l.s, l.t - m.s);
  if(abs(A) < EPS && abs(B) < EPS) return m.s; // same line
  if(abs(A) < EPS) assert(false); // !!!PRECONDITION NOT SATISFIED!!!
  return m.s + B / A * (m.t - m.s);
}

polygon convex_cut(polygon& g, line& l) {
  polygon ret{};
  rep(i, g.size()) {
    auto a = g[i], b = g[(i+1)%g.size()];
    if(ccw(l.s, l.t, a) != -1) ret.push_back(a);
    if(ccw(l.s, l.t, a) * ccw(l.s, l.t, b) < 0)
      ret.push_back(crosspoint(line{a, b}, l));
  }
  return ret;
}

bool compare(polygon& g, number V, number D, int ridx, number height) {
  line l{g[(ridx+1)%g.size()], g[ridx]};
  point v = height * ((l.t - l.s) * point{0, -1}).nml();
  l.s = l.s + v, l.t = l.t + v;
  return convex_cut(g, l).area2() * D < V * 2;
}

int main() {
  int N; number D, V;
  while(cin >> N >> D >> V && (N||D||V)) {
    polygon g{};
    rep(i, N) {
      number x, y; cin >> x >> y;
      g.push_back(point{x, y});
    }

    number ans = 0;

    rep(i, N) {
      number l = 0, h = 114514;
      rep(_, 150) {
        number mid = (l + h) / 2;
        (compare(g, V, D, i, mid) ? l : h) = mid;
      }
      ans = max(ans, l);
    }

    printf("%.10f\n", ans);
  }
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3184
final_rank: 5

code_snippet: #include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <complex>
#include <queue>
#include <deque>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <iomanip>
#include <assert.h>
#include <array>
#include <cstdio>
#include <cstring>
#include <random>
#include <functional>
#include <numeric>
#include <bitset>
#include <fstream>

using namespace std;

#define REP(i,a,b) for(int i=a;i<(int)b;i++)
#define rep(i,n) REP(i,0,n)
#define all(c) (c).begin(), (c).end()
#define zero(a) memset(a, 0, sizeof a)
#define minus(a) memset(a, -1, sizeof a)
template<class T1, class T2> inline bool minimize(T1 &a, T2 b) { return b < a && (a = b, 1); }
template<class T1, class T2> inline bool maximize(T1 &a, T2 b) { return a < b && (a = b, 1); }

typedef long long ll;
int const inf = 1<<29;

const double EPS = 1e-9;

using number = double;

struct point {
  number x, y;
  point operator + (point r) { return point{x + r.x, y + r.y}; }
  point operator + (const point& r) const { return point{x + r.x, y + r.y}; }
  point operator - (point r) { return point{x - r.x, y - r.y}; }
  point operator - (const point& r) const { return point{x - r.x, y - r.y}; }
  point operator * (point r) { return point{x*r.x - y*r.y, x*r.y + r.x*y}; }
  void operator -= (point r) { x -= r.x, y -= r.y; }
  point nml() { return point{x/sqrt(x*x+y*y), y/sqrt(x*x+y*y)}; }
};
point operator * (number k, point p) { return point{k * p.x, k * p.y}; }

struct line {
  point s, t;
};

typedef line segment;

number dot(point a, point b) {
  return a.x*b.x + a.y*b.y;
}

number cross(point a, point b) {
  return a.x*b.y - a.y*b.x;
}

number norm(point p) {
  return p.x * p.x + p.y * p.y;
}

struct polygon : public vector<point> {
  number area2() {
    number ret{};
    rep(i, this->size())
      ret += cross((*this)[i],(*this)[(i+1)%this->size()]);
    return abs(ret);
  }
};

int ccw(point a, point b, point c) {
  b -= a, c -= a;
  if(cross(b, c) > +EPS) return +1;
  if(cross(b, c) < -EPS) return -1;
  if(dot(b, c) < -EPS) return +2;
  if(norm(b) < norm(c)) return -2;
  return 0;
}

point crosspoint(const line &l, const line &m) {
  number A = cross(l.t - l.s, m.t - m.s);
  number B = cross(l.t - l.s, l.t - m.s);
  if(abs(A) < EPS && abs(B) < EPS) return m.s; // same line
  if(abs(A) < EPS) assert(false); // !!!PRECONDITION NOT SATISFIED!!!
  return m.s + B / A * (m.t - m.s);
}

polygon convex_cut(polygon& g, line& l) {
  polygon ret{};
  rep(i, g.size()) {
    auto a = g[i], b = g[(i+1)%g.size()];
    if(ccw(l.s, l.t, a) != -1) ret.push_back(a);
    if(ccw(l.s, l.t, a) * ccw(l.s, l.t, b) < 0)
      ret.push_back(crosspoint(line{a, b}, l));
  }
  return ret;
}

bool compare(polygon& g, number V, number D, int ridx, number height) {
  line l{g[(ridx+1)%g.size()], g[ridx]};
  point v = height * (l.t - l.s).nml() * point{0, -1};
  l.s = l.s + v, l.t = l.t + v;
  return convex_cut(g, l).area2() * D < V * 2;
}

int main() {
  int N; number D, V;
  while(cin >> N >> D >> V && (N||D||V)) {
    polygon g{};
    rep(i, N) {
      number x, y; cin >> x >> y;
      g.push_back(point{x, y});
    }

    number ans = 0;

    rep(i, N) {
      number l = 0, h = 114514;
      rep(_, 150) {
        number mid = (l + h) / 2;
        (compare(g, V, D, i, mid) ? l : h) = mid;
      }
      ans = max(ans, l);
    }

    printf("%.10f\n", ans);
  }
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3288
final_rank: 10

code_snippet: #include <bits/stdc++.h>
  
using namespace std;
  
#define EPS 1e-9
  
struct Point {
    double x, y;
    Point() {}
    Point(double x, double y) : x(x), y(y){}
    
    Point operator + (const Point &p) const {
        return Point(x + p.x, y + p.y);
    }
    
    Point operator - (const Point &p) const {
        return Point(x - p.x, y - p.y);
    }
  
    Point operator * (const double k) const {
        return Point(x * k, y * k);
    }
  
    Point operator / (const double k) const {
        return Point(x / k, y / k);
    }
};
  
typedef Point Vector;
  
double dot(const Point &a, const Point &b)
{
    return a.x * b.x + a.y * b.y;
}
  
double cross(const Point &a, const Point &b)
{
    return a.x * b.y - b.x * a.y;
}
  
double norm(const Point &p)
{
    return dot(p, p);
}
  
double abs(const Point &p)
{
    return sqrt(norm(p));
}
  
struct Line {
    Point s, t;
    Line(){}
    Line(Point s, Point t) : s(s), t(t) {}
};
  
vector<Vector> normal_line_vector(const Line &l)
{
    vector<Vector> vs;
    Vector v = l.t - l.s, p = v / abs(v);
    vs.push_back(Point(-p.y, p.x));
    vs.push_back(Point(p.y, p.x));
    return vs;
}
  
vector<Line> translation(const Line &l, double d)
{
    vector<Vector> nlv = normal_line_vector(l);
    vector<Line> nl;
    nl.push_back(Line(l.t + nlv[0] * d, l.s + nlv[0] * d));
    nl.push_back(Line(l.t + nlv[1] * d, l.s + nlv[1] * d));
    return nl;
}
 
int ccw(const Point &p0, const Point &p1, const 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 crosspointLL(const Line &a, const Line &b)
{
    Vector va = a.t - a.s, vb = b.t - b.s;
    double d = cross(vb, va);
    if (abs(d) < EPS) return b.s;
    return a.s + va * cross(vb, b.t - a.s) * (1.0 / d);
}
  
typedef vector<Point> Polygon;
#define curr(G, i) (G[i%G.size()])
#define next(G, i) (G[(i+1)%G.size()])
  
Polygon convex_cut(const Polygon &pg, const Line &l)
{
    Polygon res;
    for (int i = 0; i < (int)pg.size(); i++) {
    Point cp = curr(pg,i), np = next(pg,i);
    if(ccw(l.s, l.t, cp) != -1) res.push_back(cp);
    if(ccw(l.s, l.t, cp) * ccw(l.s, l.t, np) < 0){
        res.push_back(crosspointLL(Line(cp, np), l));
    }
    }
    return res;
}
 
double area(const Polygon &pg)
{
    double res = 0;
    for (int i = 0; i < (int)pg.size(); i++) {
        res += cross(pg[i], next(pg, i));
    }
    return abs(res) / 2.0;
}
  
double calc(Polygon &pg, double d, Line &l, double V)
{
    double lb = 0, ub = 25252;
    for (int i = 0; i < 150; i++) {
        double h = (lb + ub) / 2;
        vector<Line> vl = translation(l, h);
        Line nl = vl[0];       
        Polygon npg = convex_cut(pg, nl);
        double v = d * area(npg);
        if (v < V) {
            lb = h;
        } else {
            ub = h;
        }
    }
    return lb;
}
 
double solve(Polygon &pg, double d, double V)
{
    int n = pg.size();
    double max_height = 0;
    for (int i = 0; i < n; i++) {
        Line l(curr(pg, i), next(pg, i));
        max_height = max(max_height, calc(pg, d, l, V));
    }
    return max_height;
}
  
int main()
{
    int n;
    double d, V;
    while (cin >> n >> d >> V, n) {
        Polygon pg(n);
        for (int i = 0; i < n; i++) {
            cin >> pg[i].x >> pg[i].y;
        }
        printf("%.10f\n", solve(pg, d, V));
    }
    return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 1252
final_rank: 4

code_snippet: #include<bits/stdc++.h>
using namespace std;

typedef complex<double> P; //Point
typedef pair<P,P> L; //Line, Segment

const double EPS = 1e-9;

double dot(P a, P b){ return a.real() * b.real() + a.imag() * b.imag(); }
double cross(P a, P b){ return   a.real() * b.imag() - a.imag() * b.real(); }

int ccw(P a, P b, P c){
  b -= a;
  c -= a;
  if(cross(b,c) > EPS) return 1; //???????¨???????
  if(cross(b,c) < -EPS) return -1; // ????¨???????
  if(dot(b,c) < -EPS) return 2; // c -- a -- b ????????´???
  if(norm(b) < norm(c)) return -2; // a -- b -- c ????????´???
  return 0; // a -- c -- b ????????´????
}

P crossPoint(L l, L m){
  double A = cross(l.second - l.first, m.second - m.first);
  double B = cross(l.second - l.first, l.second - m.first);
  if(fabs(A) < EPS && fabs(B) < EPS) return m.first;
  else if(fabs(A) >= EPS) return m.first + B / A * (m.second - m.first);
}

void view(vector<P> G){
  cout << "view : ";
  for(int i=0;i<(int)G.size();i++) cout << G[i] << " ";
  cout << endl;
}

vector<P> convex_cut(vector<P> G, L l){
  vector<P> ans;
  for(int i=0;i<G.size();i++){
    P A = G[i];
    P B = G[(i+1)%G.size()];
    if(ccw(l.first, l.second, A) != -1) ans.push_back(A);
    if(ccw(l.first, l.second, A) * ccw(l.first, l.second, B) < 0)
      ans.push_back(crossPoint(L(A,B), l));
  }
  //view(ans);
  return ans;
}

double area(vector<P> v){
  double sum = 0.0;
  int n = v.size();
  for(int i=0;i<n;i++) sum += (real(v[i]) - real(v[(i+1)%n])) * (imag(v[i]) + imag(v[(i+1)%n]));
  return fabs(sum) / 2;
};

int N,D,V;
double dV;
L p_move( L s, double h ){
  P v = s.second - s.first;
  v = P( -v.imag(), v.real() );
  v /= abs(v);
  s.first += v*h;
  s.second += v*h;
  return s;
}

double solve( vector<P> v, L s ){
  double st = 0.0, ed = 100000.0;
  double A=area(v);
  for(int l=0;l<50;l++){
    double h = (st+ed)/2.0;
    L ns = p_move( s, h );
    double a = A-area(convex_cut( v, ns ));
    if( a < dV )
      st = h;
    else
      ed = h;
  }
  return ed;
}

int main(){
  while( ~scanf("%d%d%d",&N,&D,&V) && (N|D|V) ){
    dV = (double)V/(double)D;
    vector<P> v;
    for(int i=0;i<N;i++){
      int x,y; cin >> x >> y;
      v.push_back( P( x, y ) );
    }
    double res = 0.0;
    for(int i=0;i<N;i++){
      int nd = (i+1)%N;
      L sp = L( v[i], v[nd] );
      res = max( res, solve( v, sp ) );
    }
    printf("%.9lf\n",res);
  }
}
accuracy: 1
time_ms: 10
memory_kb: 1280
final_rank: 3