Seven miscellaneous problems training

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

Guess you like

Origin www.cnblogs.com/wzxbeliever/p/11694947.html