• 【凸包】【三分】Gym


    容易发现,圆锥体积和点的具体x、y坐标无关,只与其到z轴的距离sqrt(x*x+y*y)有关。

    于是将这些三维的点都投射到二维的xOy平面的第二象限(sqrt(x*x+y*y),z),求个上凸壳,然后在每一点处,圆锥的母线的斜率的取值范围就确定了,发现这个圆锥的体积关于圆锥母线的函数是单峰的,可以三分。

    于是枚举凸壳上每一个点,做个三分就行了。

    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #define EPS 0.00000001
    using namespace std;
    struct Point{
    	double x,y;
    };
    typedef Point Vector;
    Vector operator - (const Point &a,const Point &b){
    	return (Vector){a.x-b.x,a.y-b.y};
    }
    double Cross(const Vector &a,const Vector &b){
    	return a.x*b.y-a.y*b.x;
    }
    bool cmp(const Point &a,const Point &b){
    	return fabs(a.x-b.x)>=EPS ? a.x<b.x : a.y<b.y;
    }
    int n,e;
    Point ps[10010],qs[10010];
    double V=10000000000000.0,R,H;
    double sqr(double x){
    	return x*x;
    }
    double f(int K,double x){
    	return sqr(qs[K].y/x-qs[K].x)*(-qs[K].x*x+qs[K].y);
    }
    int main()
    {
    	freopen("dome.in","r",stdin);
    	freopen("dome.out","w",stdout);
    	double X,Y,Z,maxZ=0,maxXY=0;
    	scanf("%d",&n);
    	for(int i=0;i<n;++i){
    		scanf("%lf%lf%lf",&X,&Y,&Z);
    		ps[i]=(Point){-sqrt(X*X+Y*Y),Z};
    		maxZ=max(maxZ,Z);
    		maxXY=max(maxXY,sqrt(X*X+Y*Y));
    	}
    	ps[n++]=(Point){0,maxZ};
    	ps[n++]=(Point){-maxXY,0};
    	sort(ps,ps+n,cmp);
    	for(int i=n-1;i>=0;--i){
    		while(e>1 && Cross(qs[e-1]-qs[e-2],ps[i]-qs[e-1])<EPS){
    			--e;
    		}
    		qs[e++]=ps[i];
    	}
    	for(int i=1;i<e-1;++i){
    		double l=(qs[i-1].y-qs[i].y)/(qs[i-1].x-qs[i].x),r;
    		if(fabs(l)<EPS){
    			l+=EPS;
    		}
    		if(fabs(qs[i].x-qs[i+1].x)>=EPS){
    			r=(qs[i].y-qs[i+1].y)/(qs[i].x-qs[i+1].x);
    		}
    		else{
    			r=10000000000000.0;
    		}
    		while(r-l>EPS){
    			double m1=(l+(r-l)/3.0);
    			double m2=(r-(r-l)/3.0);
    //			printf("%lf %lf
    ",f(i,m1),f(i,m2));
    //			puts("");
    			if(f(i,m1)>f(i,m2)){
    				l=m1;
    			}
    			else{
    				r=m2;
    			}
    //			printf("%lf %lf
    ",l,r);
    		}
    		double fl=f(i,l);
    		if(fl<V){
    			V=fl;
    			R=qs[i].y/l-qs[i].x;
    			H=-qs[i].x*l+qs[i].y;
    		}
    	}
    	printf("%.3f %.3f
    ",H,R);
        return 0;
    }
  • 相关阅读:
    typedef 函数指针的使用(含例子)
    关于计算机与MCU通信及MAX232、CH340T与PL2303的区别
    CH340电路设计
    USB转串口CH340接线方法
    开漏输出、推挽输出的区别
    STM32位带操作
    STM32启动文件:startup_stm32f10x_hd.s等启动文件的简单描述
    浮点数在内存中的存储方式
    stm32启动地址
    STM32三种启动模式 boot0 boot1
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/7159662.html
Copyright © 2020-2023  润新知