Problem: Gaku decided to observe the ant's nest as a free study during the summer vacation. The transparent observation case that his grandpa prepared for his grandchildren is very unique and looks like Figure 1.

Ant nest
Figure 1



This case consists of two congruent convex polygons s1 and s2 and some rectangles. Place one of the rectangular faces other than s1 and s2 so that it touches the floor. Gogo, who started observing, noticed that the height of the soil changed depending on how the bottom was selected, even though the amount of soil contained was the same (Fig. 2).

Ant nest
Figure 2



Gogo wanted to know how high it would be depending on how the case was placed. Create a program that outputs the maximum value of the soil height by inputting the shape of the convex polygon s1, the distance d between s1 and s2, and the volume V of the soil. The soil shall level as soon as the bottom of the case is placed on the floor. The s1 shape of the transparent case is given by n vertices on the two-dimensional coordinate plane. These vertices are entered in a counterclockwise order. n is 3 or more and 100 or less, and d and V are integers of 1 or more and 10,000 or less, respectively. In addition, x and y of the coordinates (x, y) of the vertices of the polygon shall be integers of -1,000 or more and 1,000 or less, respectively. V does not exceed the volume of the case.



input

A sequence of multiple datasets is given as input. The end of the input is indicated by three zero lines. Each dataset is as follows.

1st line n d V (integer integer integer; half-width space delimited)
Coordinates of the first vertex on the second line x y (integer integer; half-width space delimited)
Coordinates of the second vertex on the third line
::
n + 1 Coordinates of the nth vertex on the 1st line


The number of datasets does not exceed 20.

output

Outputs the maximum soil height for each input dataset. The answer must not have an error greater than 0.00001.

Example

Input

4 1 1
0 0
1 0
1 2
0 2
0 0 0


Output

1.000000

Solution (in CPP):

Solution:
#define _USE_MATH_DEFINES
#include<bits/stdc++.h>
using namespace std;

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

const double EPS=1e-6;
const double INF=1e10;
const double PI=acos(-1);

typedef complex<double> Point;
typedef complex<double> Vector;
typedef vector<Point> Polygon;

struct Line
{
	Point a, b;
	Line() {}
	Line(const Point &_a, const Point &_b)
	{
		a = _a; b = _b;
	}
};

//Line????????????
struct Segment
{
	Point a, b;
	Segment() {}
	Segment(const Point &_a, const Point &_b)
	{
		a = _a; b = _b;
	}
};

struct Circle
{
	Point c;
	double r;

	Circle() {}

	Circle(const Point &_c, const double &_r)
	{
		c = _c; r = _r;
	}
};

istream& operator >> (istream& is, Point &p)
{
	double x, y;
	is >> x >> y;
	p.real(x); p.imag(y);
	return is;
}

Segment ToSegment(const Line l)
{
	return Segment(l.a, l.b);
}

Line ToLine(const Segment s)
{
	return Line(s.a, s.b);
}

//???????¨±???==
bool equals(const double &a, const double &b);
bool equals(const Vector &a, const Vector &b);

//Point?????????
bool comp(const Point &a, const Point &b);

//?§????????????????
double toRad(double a);
double toDeg(double a);

//?????¢??????
Point rotate(Point p,double d);


//??????
double dot(const Vector &a, const Vector &b);

//??????
double cross(const Vector &a, const Vector &b);

//????§???¢?????¢???
double GetArea(const Polygon &g);

//???????¨???????(O(1))
//?????¶:????????¨?????°??????
int CCW(const Point &p0, const Point &p1, const Point &p2);

//??´?????????(O(1))
bool IsOrthogonal(const Vector &a, const Vector &b);
bool IsOrthogonal(const Line &l1, const Line &l2);

//????????????(O(1))
bool IsParallel(const Vector &a, const Vector &b);
bool IsParallel(const Line &l1, const Line &l2);

//?°???±(O(1))
Point Project(const Line &s, const Point &p);

//????°?(O(1))
Point Reflect(const Line &s, const Point &p);

//?????¨??´???????????¢
double GetDistance(const Line &l, const Point &p);

//?????¨??????????????¢
double GetDistance(const Segment &s, const Point &p);

//????????¨??????????????¢
double GetDistance(const Segment &s1, const Segment &s2);

//??´?????¨?????????????????????(O(1))
bool Intersects(const Line &l, const Segment &s);

//??????????????????
bool Intersects(const Segment &l1, const Segment &l2);

//??´?????¨??´????????????(O(1))
Point GetIntersection(const Line &l1, const Line &l2);

//?????¨????????????
//?????????
//	???????????????????????°
vector<Point> GetIntersection(const Circle &c1, const Circle &c2);

//????§???¢????????????(O(n))
//?????????
//  0:???????????????
//  1:????????????
//  2:?????????
int Contains(const Polygon &g, const Point &p);

//??????(O(n))
//?????????
//	x->y????????§???????°??????????????????????????¨???????
Polygon AndrewScan(Polygon &s);

//???????§???¢?????????(O(n))
Polygon ConvexCut(const Polygon &g, const Line &l);


//-----------------------------------------------------------

bool equals(const double &a, const double &b)
{
	return abs(a - b) < EPS;
}

bool equals(const Vector &a, const Vector &b)
{
	return equals(a.real(), b.real()) && equals(a.imag(), b.imag());
}

bool comp(const Point &a, const Point &b)
{
	return equals(a.real(), b.real()) ? a.imag() < b.imag() : a.real() < b.real();
}

double dot(const Vector &a, const Vector &b)
{
	return a.real()*b.real() + a.imag()*b.imag();
}

double cross(const Vector &a, const Vector &b)
{
	return a.real()*b.imag() - a.imag()*b.real();
}

double GetArea(const Polygon &g)
{
    if(g.size()<3)return 0;
	double res = 0;
	for (int i = 1; i < g.size() - 1; i++)
	{
		res += cross(g[i] - g[0], g[i + 1] - g[0]);
	}
	return abs(res / 2);
}

int CCW(const Point &p0, const Point &p1, const Point &p2)
{
	Vector v1 = (Vector)(p1 - p0), v2 = p2 - p0;
	if (cross(v1, v2) > EPS) return COUNTER_CLOCKWISE;
	if (cross(v1, v2) < -EPS) return CLOCKWISE;
	if (dot(v1, v2) < -EPS) return ONLINE_BACK;
	if (abs(v1) < abs(v2)) return ONLINE_FRONT;
	return ON_SEGMENT;
}

bool IsOrthogonal(const Vector &a, const Vector &b)
{
	return equals(dot(a, b), 0.0);
}
bool IsOrthogonal(const Line &l1, const Line &l2)
{
	return equals(dot(l1.b - l1.a, l2.b - l2.a), 0.0);
}

bool IsParallel(const Vector &a, const Vector &b)
{
	return equals(cross(a, b), 0.0);
}
bool IsParallel(const Line &l1, const Line &l2)
{
	return equals(cross(l1.b - l1.a, l2.b - l2.a), 0.0);
}

Point Project(const Line &s, const Point &p)
{
	Vector v1 = s.b - s.a;
	Vector v2 = p - s.a;
	double r = dot(v1, v2) / norm(v1);
	return s.a + v1 * r;
}

Point Reflect(const Line &s, const Point &p)
{
	return p + (Project(s, p) - p) * 2.0;
}

double GetDistance(const Line &l, const Point &p)
{
	return abs(cross(l.a - l.b, p - l.a) / abs(l.b - l.a));
}

double GetDistance(const Segment &s, const Point &p)
{
	if (dot(s.b - s.a, p - s.a) < 0.0) return abs(p - s.a);
	if (dot(s.a - s.b, p - s.b) < 0.0) return abs(p - s.b);
	return GetDistance(ToLine(s), p);
}

double GetDistance(const Segment &s1, const Segment &s2)
{
	if (Intersects(s1, s2)) return 0.0;
	return min(min(GetDistance(s1, s2.a), GetDistance(s1, s2.b)),
			   min(GetDistance(s2, s1.a), GetDistance(s2, s1.b)));
}

bool Intersects(const Line &l, const Segment &s)
{
	return CCW(l.a, l.b, s.a)*CCW(l.a, l.b, s.b) != 1;
}

bool Intersects(const Segment &l1, const Segment &l2)
{
	return CCW(l1.a, l1.b, l2.a)*CCW(l1.a, l1.b, l2.b) <= 0 &&
		CCW(l2.a, l2.b, l1.a)*CCW(l2.a, l2.b, l1.b) <= 0;
}

Point GetIntersection(const Line &l1, const Line &l2)
{
	Vector a1 = l1.b - l1.a, a2 = l2.b - l2.a;
	Vector b1 = l2.a - l1.a, b2 = l1.a - l2.b;
	double s1 = cross(a1, b1) / 2, s2 = cross(a1, b2) / 2;
	return Point(l2.a.real() + a2.real()*s1 / (s1 + s2), l2.a.imag() + a2.imag()*s1 / (s1 + s2));
}

vector<Point> GetIntersection(const Circle &c1, const Circle &c2)
{
	vector<Point> res;
	double d, a, t;
	d = sqrt(norm((c2.c - c1.c)));
	if (d < abs(c1.r - c2.r) || c1.r + c2.r < d) return res; //?????????0
	a = acos((c1.r*c1.r + d*d - c2.r*c2.r) / (2 * c1.r*d));
	t = atan2(c2.c.imag() - c1.c.imag(), c2.c.real() - c1.c.real());
	res.push_back(Point(c1.c.real() + c1.r*cos(t + a), c1.c.imag() + c1.r*sin(t + a)));
	res.push_back(Point(c1.c.real() + c1.r*cos(t - a), c1.c.imag() + c1.r*sin(t - a)));
	if (equals(res[0], res[1])) res.pop_back(); //?????????1
	return res;
}

int Contains(const Polygon &g, const Point &p)
{
	Line l = Line(p, Point(INF, p.imag()));
	int cnt = 0, n = g.size();
	for (int i = 0; i < n; i++)
	{
		Vector a = g[i] - p;
		Vector b = g[(i + 1) % n] - p;
		if (CCW(g[i], g[(i + 1) % n], p) == 0) return 2; //?????????
		if (a.imag() > b.imag()) swap(a, b);
		if (a.imag() <= EPS && EPS < b.imag() && cross(a, b) > EPS) cnt++;
	}
	if ((cnt & 1) == 1) return 1; //????????????
	return 0; //???????????????
}

Polygon AndrewScan(Polygon &s)
{
	if (s.size() <= 2) return s;
	sort(s.begin(), s.end(), comp);
	Polygon g;
	for (int i = 0; i < s.size(); i++)
	{
		//CCW?????¨?????????==COUNTER_CLOCKWISE???????????¨???????????????
		for (int n = g.size(); n >= 2 && CCW(g[n - 2], g[n - 1], s[i]) != CLOCKWISE; n--)
		{
			g.pop_back();
		}
		g.push_back(s[i]);
	}
	for (int i = s.size() - 2; i >= 0; i--)
	{
		for (int n = g.size(); CCW(g[n - 2], g[n - 1], s[i]) != CLOCKWISE; n--)
		{
			g.pop_back();
		}
		g.push_back(s[i]);
	}
	reverse(g.begin(), g.end());
	g.pop_back();
	return g;
}

Polygon ConvexCut(const Polygon &g, const Line &l)
{
	Polygon res;
	for (int i = 0; i < g.size(); i++)
	{
		Segment s = Segment(g[i], g[(i + 1) % g.size()]);
		if (CCW(l.a, l.b, s.a) != -1) res.push_back(s.a);
		if (CCW(l.a, l.b, s.a)*CCW(l.a, l.b, s.b) == -1)
			res.push_back(GetIntersection(l, ToLine(s)));
	}
	return res;
}


//Latte
double toRad(double a){return a/180.0*PI;}
double toDeg(double a){return a*180.0/PI;}
Point rotate(Point p,double d){
    return Point(p.real()*cos(d)-p.imag()*sin(d),p.real()*sin(d)+p.imag()*cos(d));
}

//Malta

#define rep(i,n) for(int i=0;i<(n);i++)

int N;
double D,V;
Polygon g;

double calc(Polygon h){
    double lb=0,ub=INF;
    for(int latte=0;latte<100;latte++){
        double mid=(lb+ub)/2;
        Line l(Point(1,mid),Point(0,mid));
        Polygon q=ConvexCut(h,l);

        double s=GetArea(q);
        if(s*D<V)lb=mid;
        else ub=mid;
    }
    
    return lb;
}

signed main()
{
    while(scanf("%d%lf%lf",&N,&D,&V),N||D||V){
        g.resize(N);
        rep(i,N)cin>>g[i];

        double ma=0;
        rep(i,N){
            Polygon h(N);
            rep(j,N)h[j]=g[(j+i)%N]-g[i];
            Point a=h[1]-h[0];
            double t=atan2(a.imag(),a.real());
            rep(j,N)h[j]=rotate(h[j],-t);
            ma=max(ma,calc(h));
        }
        printf("%.20lf\n",ma);
    }
	return 0;
}