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 _CRT_SECURE_NO_WARNINGS
//#define _GLIBCXX_DEBUG
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
//#define int ll
//#define endl "\n"
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int,int> pii;
#define all(c) (c).begin(), (c).end()
#define loop(i,a,b) for(ll i=a; i<ll(b); i++)
#define rep(i,b) loop(i,0,b)
#define pb push_back
#define eb emplace_back
#define mp make_pair
#define mt make_tuple
template<class T> ostream & operator<<(ostream & os, vector<T> const &);
template<int n, class...T> typename enable_if<(n>=sizeof...(T))>::type _ot(ostream &, tuple<T...> const &){}
template<int n, class...T> typename enable_if<(n< sizeof...(T))>::type _ot(ostream & os, tuple<T...> const & t){ os << (n==0?"":" ") << get<n>(t); _ot<n+1>(os, t); }
template<class...T> ostream & operator<<(ostream & os, tuple<T...> const & t){ _ot<0>(os, t); return os; }
template<class T, class U> ostream & operator<<(ostream & os, pair<T,U> const & p){ return os << "(" << p.first << ", " << p.second << ") "; }
template<class T> ostream & operator<<(ostream & os, vector<T> const & v){ rep(i,v.size()) os << v[i] << (i+1==(int)v.size()?"":" "); return os; }
template<class T> inline bool chmax(T & x, T const & y){ return x<y ? x=y,true : false; }
template<class T> inline bool chmin(T & x, T const & y){ return x>y ? x=y,true : false; }
#ifdef DEBUG
#define dump(...) (cerr<<#__VA_ARGS__<<" = "<<mt(__VA_ARGS__)<<" ["<<__LINE__<<"]"<<endl)
#else
#define dump(...)
#endif
// ll const mod = 1000000007;
// ll const inf = 1LL<<60;

typedef long double Real;
#define EPS (1e-10)
#define EQ(a,b) (abs(a-b) < EPS)
#define LE(a,b) (EQ(a,b) || a < b)
#define GE(a,b) (EQ(a,b) || b < a)

#define CR const &

struct Point {
    Real x, y;
    explicit Point (Real x_ = 0, Real y_ = 0);
    explicit Point (Real x_);
    Point operator + (Point CR p) const;
    Point operator - (Point CR p) const;
    Point operator * (Point CR p) const;
    Point operator / (Point CR p) const;
    Point operator * (Real k) const;
    Point operator / (Real k) const;
    bool operator < (Point CR p) const;
    bool operator == (Point CR p) const;
};
Real dot(Point CR p, Point CR q) { return p.x * q.x + p.y * q.y; }
Real cross(Point CR p, Point CR q) { return p.x * q.y - p.y * q.x; }
Real norm(Point CR p){ return dot(p,p); }
Real abs(Point CR p){ return sqrt(norm(p)); }
Point inv(Point CR p){ return Point(p.x,-p.y) / abs(p); }
Real arg(Point CR p){ return atan2(p.y,p.x); }
ostream & operator << (ostream & os, Point CR p){ return os << "(" << p.x << "," << p.y << ")"; }
Point::Point (Real x_, Real y_) : x(x_), y(y_) {}
Point::Point (Real x_) : x(x_), y(0) {}
Point Point::operator + (Point CR p) const { return Point(x + p.x, y + p.y); }
Point Point::operator - (Point CR p) const { return Point(x - p.x, y - p.y); }
Point Point::operator * (Point CR p) const { return Point(x*p.x - y*p.y, x*p.y + y*p.x); }
Point Point::operator / (Point CR p) const { return Point(*this) * inv(p); }
Point Point::operator * (Real k) const { return Point(x * k, y * k); }
Point Point::operator / (Real k) const { return Point(x / k, y / k); }
bool Point::operator < (Point CR p) const { return std::abs(x - p.x) < EPS ? x < p.x : y < p.y; }
bool Point::operator == (Point CR p) const { return EQ(*this,p); }
bool comp_x(Point CR p, Point CR q){ return !EQ(p.x,q.x) ? p.x < q.x : p.y < q.y; }
bool comp_y(Point CR p, Point CR q){ return !EQ(p.y,q.y) ? p.y < q.y : p.x < q.x; }
struct Segment {
    Segment(Point a = Point(), Point b = Point()){ p[0] = a, p[1] = b; }
    Point p[2];
    Point & operator [] (int k) { return p[k]; }
    const Point & operator [] (int k) const { return p[k]; }
};

struct Line {
    Line(Point a = Point(), Point b = Point()){ p[0] = a, p[1] = b; }
    Point p[2];
    Point & operator [] (int k) { return p[k]; }
    const Point & operator [] (int k) const { return p[k]; }
};

struct Circle {
    Point p; Real r;
};

typedef vector<Point> Polygon;

enum {
    CCW = +1,
    CW = -1,
    BACK = +2,
    FRONT = -2,
    ON = 0
};
int ccw(Point CR p0, Point CR p1, Point CR p2){
    Point a = p1 - p0;
    Point b = p2 - p0;
    if(cross(a,b) > EPS) return CCW;
    if(cross(a,b) < -EPS) return CW;
    if(dot(a,b) < -EPS) return BACK;
    if(norm(a) < norm(b)) return FRONT;
    return ON;
}

Polygon andrewScan(Polygon ps){
    // 同一直線上に3点以上存在する場合に
    // ==CW  -> それらを全て含める
    // !=CCW -> 両端以外の点を除く
    int N = ps.size(), k = 0;
    sort(all(ps),comp_x);
    Polygon res(N*2);
    for(int i=0; i<N; i++) {
        while(k>=2 && ccw(res[k-2], res[k-1], ps[i])==CW) k--;
        // while(k>=2 && ccw(res[k-2], res[k-1], ps[i])!=CCW) k--;
        res[k++] = ps[i];
    }
    int t = k+1;
    for(int i=N-2; i>=0; i--) {
        while(k>=t && ccw(res[k-2], res[k-1], ps[i])==CW) k--;
        // while(k>=t && ccw(res[k-2], res[k-1], ps[i])!=CCW) k--;
        res[k++] = ps[i];
    }
    res.resize(k-1);
    return res;
}

bool intersectLL(const Line &l, const Line &m) {
    return abs(cross(l[1]-l[0], m[1]-m[0])) > EPS || // non-parallel
                                                                 abs(cross(l[1]-l[0], m[0]-l[0])) < EPS;   // same line
}
bool intersectLS(const Line &l, const Line &s) {
    return cross(l[1]-l[0], s[0]-l[0])*       // s[0] is left of l
        cross(l[1]-l[0], s[1]-l[0]) < EPS; // s[1] is right of l
}
bool intersectLP(const Line &l, const Point &p) {
    return abs(cross(l[1]-p, l[0]-p)) < EPS;
}
bool intersectSS(const Line &s, const Line &t) {
    return ccw(s[0],s[1],t[0])*ccw(s[0],s[1],t[1]) <= 0 &&
        ccw(t[0],t[1],s[0])*ccw(t[0],t[1],s[1]) <= 0;
}
bool intersectSP(const Line &s, const Point &p) {
    return abs(s[0]-p)+abs(s[1]-p)-abs(s[1]-s[0]) < EPS; // triangle inequality
}

Point projection(const Line &l, const Point &p) {
    double t = dot(p-l[0], l[0]-l[1]) / norm(l[0]-l[1]);
    return l[0] + (l[0]-l[1])*t;
}
Point reflection(const Line &l, const Point &p) {
    return p + (projection(l, p) - p) * 2;
}
double distanceLP(const Line &l, const Point &p) {
    return abs(p - projection(l, p));
}
double distanceLLine(const Line &l, const Line &m) {
    return intersectLL(l, m) ? 0 : distanceLP(l, m[0]);
}
double distanceLS(const Line &l, const Line &s) {
    if (intersectLS(l, s)) return 0;
    return min(distanceLP(l, s[0]), distanceLP(l, s[1]));
}
double distanceSP(const Line &s, const Point &p) {
    const Point r = projection(s, p);
    if (intersectSP(s, r)) return abs(r - p);
    return min(abs(s[0] - p), abs(s[1] - p));
}
double distanceSS(const Line &s, const Line &t) {
    if (intersectSS(s, t)) return 0;
    return min(min(distanceSP(s, t[0]), distanceSP(s, t[1])),
               min(distanceSP(t, s[0]), distanceSP(t, s[1])));
}
Point crosspoint(const Line &l, const Line &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
    if (abs(A) < EPS) assert(false); // !!!PRECONDITION NOT SATISFIED!!!
    return m[0] + (m[1] - m[0]) * B / A;
}

pair<Polygon,Polygon> convexCut(Polygon const & g, Line const & l) {
    Polygon right, left;
    int n = g.size();
    rep(i,n){
        Point p1 = g[i], p2 = g[(i+1)%n];
        int c1 = ccw(l[0],l[1],p1), c2 = ccw(l[0],l[1],p2);
        if(c1!=CW) right.push_back(p1);
        if(c1!=CCW) left.push_back(p1);
        if(c1*c2 < 0){
            Point cp = crosspoint(Line(p1,p2),l);
            right.push_back(cp);
            left.push_back(cp);
        }
    }
    return make_pair(left,right);
}

Real area(Polygon const & g){
    Real s = 0;
    int n = g.size();
    rep(i,n) s += cross(g[i], g[(i+1)%n]);
    return abs(s/2);
}

Real solve(Polygon const & g, Real s){
    Real y0 = 0, y1 = 100000;
    rep(i,200){
        Real m = (y0+y1)/2;
        Point a(1,m), b(0,m);
        Real s_ = area(convexCut(g,Line(a,b)).second);
        if(s_+EPS > s) y1 = m; else y0 = m;
    }
    return y0;
}

int main(){
    int n,d,v;
    while(cin >> n >> d >> v && n){
        Real s = (Real)v/d;
        Polygon g(n);
        rep(i,n){
            int x,y;
            cin >> x >> y;
            g[i] = Point(x,y);
        }
        Real ans = 0;
        rep(i,n){
            for(int j=n-1;j>=0;j--) g[j] = g[j] - g[0];
            Point dir = (g[1]-g[0]) / abs(g[1]-g[0]);
            rep(j,n) g[j] = g[j]/dir;
            Real t = solve(g,s);
            ans = max(ans, t);
            rotate(g.begin(), g.begin()+1, g.end());
        }
        printf("%.10lf\n", double(ans));
    }
}