https://www.luogu.org/problem/P1663
First, the scope of this problem of data comparison water, O (N * N) may be over, but will not say
Consider smaller
To find all the problems into a straight line intersects the highest point
Consider dichotomous answers,
The answer must be greater than before, but not necessarily the smallest
The answer can not be less than satisfying conditions
So you can answer half
And then consider how check function to determine
At this time, consider two points answer C is , in the cross slope> 0 a straight line at one point, this point left -side portion will be able to take
Likewise slope <0 line
Speak may not be clear, but the code is very clear
code:
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=5005;
struct ad{ int x,y; } a[maxn];
struct line{ double k,b; } b[maxn]; //存直线的表达式
int n; double l,r,mid,L,R,ans;
inline int read(){
int ret=0; char ch=getchar();
while (ch<'0'||ch>'9') ch=getchar();
while (ch>='0'&&ch<='9') ret=ret*10+ch-'0',ch=getchar();
return ret;
}
inline bool check(double x){
L=-2e9,R=2e9;
for (int i=1;i<n;i++){
if (b[i].k<0) L=max(L,(x-b[i].b)/b[i].k); //由于k可能小于0,注意不等式两边同除以负数要变号
if (b[i].k>0) R=min(R,(x-b[i].b)/b[i].k);
if (b[i].k==0&&b[i].b>x) return 0; //k等于0的话一除就暴了,注意特判
}
return L<=R;
}
int main(){
freopen("hill.in","r",stdin);
freopen("hill.out","w",stdout);
n=read();
for (int i=1;i<=n;i++) a[i].x=read(),a[i].y=read();
for (int i=1;i<n;i++){
b[i].k=1.0*(a[i].y-a[i+1].y)/(a[i].x-a[i+1].x); //自己推一下的话,应该能懂
b[i].b=1.0*a[i].y-b[i].k*a[i].x;
}
l=0,r=1000000;
while (r-l>=0.001){ //二分小数的办法
mid=(l+r)/2.0;
if (check(mid)) ans=r=mid; else l=mid;
}
printf("%.2lf\n",ans);
return 0;
}