AOJ0253 Ant Nest

2015/06/21 (Sun) AOJ 幾何

問題

問題文

方針

全ての側面を底面にしておいた時の高さを求め,最小値を取る. 高さは二分探索で求める.

実装

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