LDUOJ —— Montaña (geometría computacional + dicotomía + precisión)

H. La
descripción de la montaña
da una montaña como se muestra en la imagen.

Ahora tenemos que instalar una luz en cierta parte de la montaña para que se pueda ver cualquier parte de la montaña. Da la coordenada y más pequeña, el signo + en la figura es el lugar donde se instala la luz con la coordenada y más pequeña.

En la
primera línea de Entrada, un número N indica que la montaña está compuesta por N puntos, y las siguientes N líneas dan la estructura de la montaña de izquierda a derecha. Cada línea tiene dos números Xi, Yi, que representan un punto de inflexión. Asegúrese de que Xi> Xi − 1 (1 <i≤N).

La salida
solo genera una línea, que es la coordenada y más pequeña. Cuando su respuesta difiere de la respuesta estándar en 0.01, se considera correcta.

Muestras
Entrada Copia
6
0 0
10 0
11 1
15 1
16 0
25 0
Salida
3.00
Sugerencia
30% de los datos, 1≤N≤50;
100% de los datos, 1≤N≤5000, 0≤Xi, Yi≤100000 , garantizado La respuesta no supera el 1.000.000.
Idea:
Cuénteme sobre todo el proceso de ser atrapado por esta tarjeta de preguntas.
En primer lugar, al ver la altura más baja y, la primera reacción es de dos puntos, y se siente monótona, así que pretendo hacer un disparo imprudente.
Entonces, ¿cómo comprobarlo?
Necesitamos encontrar la intersección de cada línea con la altura de enumeración actual. Por ejemplo, cuando la pendiente de la línea es menor que 0, se pueden ver todos los puntos a la izquierda del punto. Para cumplir con los requisitos de todas las líneas rectas, se toma el punto final izquierdo máximo para todas las líneas rectas con una pendiente menor que 0.
De la misma forma, cuando la pendiente de la recta es mayor que 0, se pueden ver todos los puntos a la derecha del punto y se toma el mínimo del extremo derecho.
Cuando el intervalo es legal, la altura es legal.
Sin embargo, si la pendiente del punto faltante es 0, es bueno juzgarlo. La razón específica saldrá después de hacer un dibujo.
Algunos pequeños consejos:
1. Tenga en cuenta que la pendiente es y / x
2. Tenga en cuenta que la precisión en el proceso de cálculo y la precisión de la respuesta de salida son diferentes

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll,ll>PLL;
typedef pair<int,int>PII;
typedef pair<double,double>PDD;
#define I_int ll
inline ll read()
{
    
    
    ll x=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9')
    {
    
    
        if(ch=='-')f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
    {
    
    
        x=x*10+ch-'0';
        ch=getchar();
    }
    return x*f;
}
#define read read()
#define closeSync ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define multiCase int T;cin>>T;for(int t=1;t<=T;t++)
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i<(b);i++)
#define per(i,a,b) for(int i=(a);i>=(b);i--)
#define perr(i,a,b) for(int i=(a);i>(b);i--)
ll ksm(ll a,ll b,ll p)
{
    
    
    ll res=1;
    while(b)
    {
    
    
        if(b&1)res=res*a%p;
        a=a*a%p;
        b>>=1;
    }
    return res;
}
#define PI acos(-1)
const double eps=1e-8;
const int maxn=1e6+100;
struct node{
    
    
    double x,y;
}a[maxn];///存点
struct node1{
    
    
    double k,b,x;
}b[maxn];///存线段
int n;
bool check(double y){
    
    
    double l=-1e9,r=1e9;
    for(int i=2;i<=n;i++){
    
    
        if(b[i].k<0){
    
    
            double t=(y-b[i].b)/b[i].k;
            l=max(l,t);
        }
        else if(b[i].k>0){
    
    
            double t=(y-b[i].b)/b[i].k;
            r=min(r,t);
        }
        else if(b[i].k==0&&y<b[i].b) return 0;
    }
    if(l<=r) return 1;
    return 0;
}
int main()
{
    
    
    n=read;

    rep(i,1,n){
    
    
        cin>>a[i].x>>a[i].y;
        if(i>1){
    
    
            b[i].k=(a[i].y-a[i-1].y)/(a[i].x-a[i-1].x);
            b[i].b=a[i].y-b[i].k*a[i].x;
            b[i].x=a[i].x;
        }
    }
    double l=0,r=1e9;
    double res=0;
    while((r-l)>eps){
    
    
        double mid=(l+r)/2;
        if(check(mid)) res=mid,r=mid-eps;
        else l=mid+eps;
        ///cout<<mid<<" "<<l<<" "<<r<<endl;
    }
    printf("%.2lf\n",res);
    return 0;
}

Supongo que te gusta

Origin blog.csdn.net/weixin_45675097/article/details/114459258
Recomendado
Clasificación