zoukankan      html  css  js  c++  java
  • Bzoj4570--Scoi2016妖怪

    把每一个妖怪看出平面上的一个点(x,y),场地参数k=-a/b;

    那么每个妖怪的战斗力即为过点(x,y)斜率为k的直线与坐标轴的交点的和

    稍微画下图可以看出如果是最大战力的妖怪一定是在所有点所形成的右上凸包上

    维护一个凸包,枚举凸包每一个点是最强妖怪时的最弱战力

    要使一个点所形成的是最强战力,那么有过这个点i的斜率k i-1<k i<k i+1,算出每个点的最佳斜率k',如果k'满足条件则代入k'更新答案,再用i与i+1的斜率更新一下答案

    代码如下 :

    #include<bits/stdc++.h>
    #define MAXN 1000005
    #define MAXM 150005
    #define fix 40000
    #define INF 1000000000
    #define eps 1e-9
    #define LL long long
    using namespace std;
    
    struct P{
        double x,y;
        bool operator < (P b) const {return x>b.x;}
        double comp() {return x+y+2*sqrt(x*y);}
    }p[MAXN],tb[MAXN];
    double k[MAXN],ans=INF;
    int n,top,ed;
    
    inline double cross(P a,P b,P c) {
        a.x-=b.x;a.y-=b.y;b.x-=c.x;b.y-=c.y;
        return b.x*a.y-b.y*a.x;
    }
    inline double Get_K(P a,P b) {return (a.y-b.y)/(a.x-b.x);}
    
    int main() {
        scanf("%d",&n);
        for(int i=1;i<=n;i++) {
            scanf("%lf%lf",&p[i].x,&p[i].y);
        }
        sort(p+1,p+1+n);
        for(int i=1;i<=n;i++) {
            while(top>1&&cross(p[i],tb[top],tb[top-1])<0) top--;
            tb[++top]=p[i];
        }
        k[0]=-INF;
        for(int i=1;i<=top;i++) {
            k[i]=Get_K(tb[i+1],tb[i]);
            ed=i;if(k[i]>=0) break;
        }
        k[ed]=-eps;
        for(int i=1;i<=ed;i++) {
            double mk=-sqrt(tb[i].y/tb[i].x),cg=INF,he;
            if(mk>k[i-1]&&mk<k[i]) cg=tb[i].comp();
            he=tb[i].x+tb[i].y-k[i]*tb[i].x-tb[i].y/k[i];
            cg=cg>he?he:cg;ans=ans>cg?cg:ans;
        }
        printf("%.4lf",ans);
        return 0;
    } 

    为了方便是把右上凸包的首尾斜率设置了一下

  • 相关阅读:
    forward redirect 区别
    request response 区别
    Java集合 初步了解
    通过session统计当前在线人数
    Session保存用户名到Session域对象中
    Cookie获取用户的访问记录
    表单中有关于爱好的多选框, 篮球,足球,游泳,跑步, 再有一个多选框,代表全选
    jQuery常用子元素过滤选择器
    jQuery常用属性过滤选择器
    jQuery常见可见性过滤选择器
  • 原文地址:https://www.cnblogs.com/ihopenot/p/5910902.html
Copyright © 2011-2022 走看看