您的位置:首页 > 其它

uva 1473 - Dome of Circus

2013-08-19 19:48 295 查看
题意:给定 n 个空间中的点,任务是找一个底面在 z=0 平面上,中心在(0,0,0)的体积最小的圆锥,包含所有点。



#include<iostream>
#include<cmath>
#include<algorithm>
#include<iomanip>
#define pi (2.0*asin(1.0))
#define div(a) ((a)*(a)*(a))
#define eps 1e-6

using namespace std;
const double inf=8000000000000000000;

int m,n;

int sig(double a)
{
return (a>eps)-(a<-eps);
}

struct point
{
double x,y;
point(double xx=0,double yy=0):x(xx),y(yy){}
}p[10010],ch[10010];

bool operator < (point a,point b)
{
return sig(a.x-b.x)<0 || (sig(a.x-b.x)==0 && sig(a.y-b.y)<0);
}
point operator - (point a,point b)
{
return point(a.x-b.x,a.y-b.y);
}
double cross(point a,point b)
{
return a.x*b.y-a.y*b.x;
}
void convex()
{
int i;
sort(p,p+n);
m=0;
for(i=0;i<n;i++)
{
while(m>1 && sig(cross(ch[m-1]-ch[m-2],p[i]-ch[m-2]))<=0) m--;
ch[m++]=p[i];
}
int k=m;
for(i=n-2;i>=0;i--)
{
while(m>k && sig(cross(ch[m-1]-ch[m-2],p[i]-ch[m-2]))<=0) m--;
ch[m++]=p[i];
}
if(n>1) m--;
}

int main()
{
int i,mx;
double x,y,z,k,k1,k2,mv,mk,v;
while(cin>>n)
{
for(i=0;i<n;i++)
{
cin>>x>>y>>z;
p[i]=point(sqrt(x*x+y*y),z);
}
convex();
mv=inf;
int i1,i2;
if(m>1)
{
k2=inf;
for(i=0;i<m;i++)
{
i2=(i+1)%m;
if(sig(ch[i2].x-ch[i].x)<0)
{
k=2*ch[i].y/ch[i].x;
k1=k2;
k2=(ch[i2].y-ch[i].y)/(ch[i].x-ch[i2].x);
if(sig(k2)<=0) break;
if(sig(k-k2)<0) k=k2;
else if(sig(k-k1)>0) k=k1;
v=k/3*pi*div(ch[i].x+ch[i].y/k);
if(sig(mv-v)>0)
{
mv=v;
mx=i;mk=k;
}
}
else if(sig(ch[i2].x-ch[i].x)==0 && ch[i2].y<ch[i].y) break;
}
i%=m;i1=(m+i-1)%m;
if(sig(ch[i1].x-ch[i].x)==0) k1=-1;
else k1=(ch[i].y-ch[i1].y)/(ch[i1].x-ch[i].x);
k=2*ch[i].y/ch[i].x;
if(sig(k1)>0 && sig(k-k1)>0) k=k1;
v=k/3*pi*div(ch[i].x+ch[i].y/k);
if(sig(mv-v)>0)
{
mv=v;
mx=i;mk=k;
}
x=ch[mx].x;y=ch[mx].y;
k=mk;
}
else
{
x=ch[0].x;y=ch[0].y;
k=2*y/x;
}
double h=y+k*x;
double x=h/k;
cout<<fixed<<setprecision(3)<<h<<" "<<x<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ACM-ICPC C AMP uva 凸包