题目
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;
}