AOJ 2256 Divide the Cake

ケーキの端にイチゴが乗ってる時(sample1)の対処をメモ。
len(Y)は片方を(0,Y)に固定したときに等分できる右側の部分の長さを返す関数。
ただ、(0,Y)にイチゴがあると色々面倒なので+eps,-epsの2つに分けて処理した。
誤差怖かったけど通ったので良かった(小並感)

int W,H,N;
int x[210],y[210];
double len(double Y)
{
    vector<double> v;
    for(int i=0;i<2*N;i++)v.pb(atan2(y[i]-Y,x[i]));
    sort(all(v));
    double low = tan(v[N-1])*(double)W + Y;
    double high = tan(v[N])*(double)W + Y;
    low = max(low,0.0);
    low = min(low,(double)H);
    high = max(high,0.0);
    high = min(high,(double)H);
    return high-low;
}
int main()
{
    while(1)
    {
        scanf("%d %d %d",&W,&H,&N);
        if(W==0&&H==0&&N==0)break;
        for(int i=0;i<N*2;i++)scanf("%d %d",&x[i],&y[i]);
        vector<P> v;
        for(int i=0;i<N*2;i++)v.pb(P(x[i],y[i]));
        v.pb(P(W,0));v.pb(P(W,H));
        vector<double> border;
        for(int i=0;i<v.size();i++)
        {
            for(int j=i+1;j<v.size();j++)
            {
                if(v[i].fi==v[j].fi)continue;
                double res = (double)v[i].sec-(double)v[i].fi*(double)(v[j].sec-v[i].sec)/(double)(v[j].fi-v[i].fi);
                if(0.0<=res&&res<=(double)H)border.pb(res);
            }
        }
        border.pb(0.0);border.pb(H);
        sort(all(border));
        border.erase(unique(all(border)),border.end());
        double ans = 0.0;
        for(int i=0;i<border.size()-1;i++)ans+=(len(border[i]+eps)+len(border[i+1]-eps))/2.0*(border[i+1]-border[i]);
        ans /= (double)H;
        ans /= (double)H;
        printf("%.12f\n",ans);
    }
    return 0;
}