• bzoj4570: [Scoi2016]妖怪


    传送门

    只会瞎那啥三分,然后正解是凸包。

    题解传送门

    式子摆出来,发现可以看成二维平面上一堆斜率为-a/b的点的横纵截距和。

    然后一坨平行线中,值最大的就是最右上的直线。

    一个点何时会成为最大值呢,维护一个右上凸包即可。

    然后对于凸包上每个点计算答案,取min。

    //Achen
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    #include<vector>
    #include<queue>
    #include<ctime>
    #include<cmath>
    const int N=1e6+7;
    typedef double db;
    using namespace std;
    int n,que[N],top;
    
    template<typename T> void read(T &x) {
        char ch=getchar(); x=0; T f=1;
        while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
        if(ch=='-') f=-1,ch=getchar();
        for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
    }
    
    struct node {
        int x,y;
        friend bool operator <(const node&A,const node&B) {
            return A.x<B.x||(A.x==B.x&&A.y<B.y);
        }
    }p[N];
    
    double get_xl(int i,int j) {
        if(j==0) return 0;
        if(p[i].x==p[j].x) return 0;
        return ((db)p[i].y-p[j].y)/(((db)p[i].x-p[j].x)*1.0);
    }
    
    int main() {
        read(n);
        for(int i=1;i<=n;i++) {
            read(p[i].x); read(p[i].y);
        }
        sort(p+1,p+n+1); 
        for(int i=1;i<=n;i++) {
            while(top&&(get_xl(i,que[top])>=0||(top>1&&get_xl(i,que[top])>=get_xl(que[top],que[top-1])))) 
                top--;
            que[++top]=i;
        }
        db l,ans;
        for(int i=top;i>=1;i--) {
            int a=que[i],b=que[i-1];
            db r=get_xl(a,b);
            db mk=sqrt((db)p[a].y/((db)p[a].x*1.0));
            if(i==top) {
                if(-mk<=r) ans=2.0*sqrt(p[a].x*p[a].y)+p[a].x+p[a].y;
                else ans=-(r*p[a].x+(db)p[a].y/(r*1.0))+p[a].x+p[a].y;
            }
            else {
                if((-mk>=l&&-mk<=r)) ans=min(ans,2.0*sqrt(p[a].x*p[a].y)+p[a].x+p[a].y);
                else {
                    if(r) ans=min(ans,-(r*p[a].x+(db)p[a].y/(r*1.0))+p[a].x+p[a].y);
                    ans=min(ans,-(l*p[a].x+(db)p[a].y/(l*1.0))+p[a].x+p[a].y);
                }
            }
            l=r;
        }
        printf("%.4lf
    ",ans);
        return 0;
    }
    /*
    3
    2 5
    3 4
    4 1
    */
    View Code
  • 相关阅读:
    WIN10平台下基于Anaconda环境的pyOpt安装
    「Java分享客栈」随时用随时翻:微服务链路追踪之zipkin搭建
    【Java分享客栈】未来迈向高级工程师绕不过的技能:JMeter压测
    全网唯一 | 互联网公司微信支付宝服务商入驻流程图文指南
    shellcode编写
    C语言函数调用栈
    栈溢出基础
    Git学习笔记
    mixer类型 DAPM kcontrol 写流程
    BE dailink fixup callback函数
  • 原文地址:https://www.cnblogs.com/Achenchen/p/8385820.html
Copyright © 2020-2023  润新知