zoukankan      html  css  js  c++  java
  • LOJ#2015. 「SCOI2016」妖怪(凸包)

    传送门

    首先可以把每个妖怪看成二维平面上的一个点,那么每一个环境((a,b))就可以看成一条斜率(k=-frac{b}{a})的过该点的直线,战斗力就是这条直线在两坐标轴上的截距之和

    对于每一个妖怪来说,它的战斗力为(x+y-kx-frac{y}{k}),后面是个对勾函数,当(k=-sqrt{frac{y}{x}})的时候函数取到最小值

    那么我们维护一个右上凸壳,然后对于每一个点先用它和上一个点的直线更新答案,然后计算它的最优斜率,如果这个斜率的直线在凸包上刚好切到这一个点那么就更新答案

    复杂度(O(nlogn))

    我怎么感觉以前好像做过这题

    //minamoto
    #include<bits/stdc++.h>
    #define R register
    #define ll long long
    #define inline __inline__ __attribute__((always_inline))
    #define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
    #define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
    #define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
    template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
    using namespace std;
    char buf[1<<21],*p1=buf,*p2=buf;
    inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
    int read(){
        R int res,f=1;R char ch;
        while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
        for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
        return res*f;
    }
    const int N=1e6+5;const double eps=1e-10;
    inline double abs(R double x){return x<-eps?-x:x;}
    inline int sgn(R double x){return x<-eps?-1:x>eps;}
    struct node{
    	int x,y;
    	inline node(){}
    	inline node(R int xx,R int yy):x(xx),y(yy){}
    	inline node operator +(const node &b)const{return node(x+b.x,y+b.y);}
    	inline node operator -(const node &b)const{return node(x-b.x,y-b.y);}
    	inline ll operator *(const node &b)const{return 1ll*x*b.y-1ll*y*b.x;}
    	inline bool operator <(const node &b)const{return x==b.x?y>b.y:x<b.x;}
    	inline double K(){return -sqrt(1.0*y/x);}
    	friend double sl(const node &a,const node &b){return (0.0+b.y-a.y)/(b.x-a.x);}
    	inline double calc(R double k){return !sgn(k)?1e18:x+y-k*x-y/k;}
    }p[N],st[N];
    int n,top;double ans=1e18,k,sp[N];
    int main(){
    //	freopen("testdata.in","r",stdin);
    	n=read();
    	fp(i,1,n)p[i].x=read(),p[i].y=read();
    	sort(p+1,p+1+n);
    	st[++top]=p[1];
    	fp(i,2,n){
    		while(top>1&&(p[i]-st[top-1])*(st[top]-st[top-1])<0)--top;
    		st[++top]=p[i];
    	}
    	fp(i,1,top-1)sp[i]=sl(st[i],st[i+1]);sp[top]=-1e18;
    	fp(i,2,top){
    		k=st[i].K();
    		if(sgn(sp[i-1]-k)>=0&&sgn(k-sp[i])>=0)cmin(ans,st[i].calc(k));
    		cmin(ans,st[i].calc(sp[i-1]));
    	}
    	k=st[1].K();
    	if(sgn(k-sp[1])>=0)cmin(ans,st[1].calc(k));
    	printf("%.4lf
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    SQL Server 阻止了对组件 'Ole Automation Procedures' 的 过程'sys.sp_OACreate' 的访问
    谷歌浏览器扩展程序manifest.json参数详解
    获取天气api
    UVA 10385 Duathlon
    UVA 10668 Expanding Rods
    UVALIVE 3891 The Teacher's Side of Math
    UVA 11149 Power of Matrix
    UVA 10655 Contemplation! Algebra
    UVA 11210 Chinese Mahjong
    UVA 11384 Help is needed for Dexter
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/10695702.html
Copyright © 2011-2022 走看看