题目

https://www.luogu.org/problemnew/show/P1663

思路

求出直线的斜率,截距等资料。
二分枚举高度y。
check(mid)函数:如果对于任意一条直线,存在(x,y)在直线的上端或在直线上则true.
判断时,通过直线方程求出满足y的点(x0,y),
对于k>0,则x的解集的右端点取x0.
对于k<0,则左端点取x0.
对于k==0,直接看b和mid的关系.
最后(l,+inf)…(-inf,r)等等取交集,即判断return l<=r即可。

代码

#include <bits/stdc++.h>
using namespace std;
const int MN=5005;
typedef long long ll;

struct line
{
    double k,b;
    int x1,y1,x2,y2;
    void solve()
    {
        k=((double)(y2-y1))/((double)(x2-x1));
        b=(double)y2-k*(double)x2;
    }
}l[MN];
/*double cross(line l1,line l2)
{
    if (l1.k==l2.k) return 0.00;
    return (l1.b*l2.k-l2.b*l1.k)/(l2.k-l1.k);
}*/
int n;
bool check(double x)
{
    double L=-2e9,R=2e9;
    for (int i=1;i<n;++i)
    {
        if (l[i].k<0) L=max(L,(x-l[i].b)/l[i].k);
        else if (l[i].k>0) R=min(R,(x-l[i].b)/l[i].k);
        else if (x<l[i].b) return false;
    }
    return L<=R;
}
ll read(){
    ll f=1,x=0;char c=getchar();
    while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}
    while(c<='9'&&c>='0'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
int main()
{
    n=read();
    int x1,y1,x2,y2;x1=read();y1=read();
    for (int i=2;i<=n;++i)
    {
        x2=read();y2=read();
        l[i-1].x1=x1,l[i-1].y1=y1,l[i-1].x2=x2,l[i-1].y2=y2;
        l[i-1].solve();
        x1=x2,y1=y2;
    }
    double L=0.00,R=2e9;
    while (L+0.001<=R)
    {
        double mid=(L+R)/2.00;
        if (!check(mid)) L=mid; //don't need to plus 1.
        else R=mid;
    }
    printf("%.2lf",R);
    return 0;
}