|
Ultimate Weapon
Description In year 2008 of the Cosmic Calendar, the Aliens send a huge armada towards the Earth seeking after conquest. The humans now depend on their ultimate weapon to retain their last hope of survival. The weapon, while capable of creating a continuous, closed and convex lethal region in the space and annihilating everything enclosed within, unfortunately exhausts upon each launch a tremendous amount of energy which is proportional to the surface area of the lethal region. Given the positions of all battleships in the Aliens' armada, your task is to calculate the minimum amount of energy required to destroy the armada with a single launch of the ultimate weapon. You need to report the surface area of the lethal region only. Input The first line contains one number N -- the number of battleships.(1 ≤ N ≤ 500) Output The minimal area rounded to three decimal places. Sample Input 4 0 0 0 4 0 0 2 3 0 1 1 2 Sample Output 19.137 Hint
There are no four coplaner battleships.
Source
POJ Founder Monthly Contest – 2008.03.16, Jiang Liyang
|
题目:http://poj.org/problem?id=3528
Poj 2974与这道题类似
题意:给你空间n个点,让你求一个包含所有点的凸多面体,使得面积最小。。。
分析:面积最小的多面体,肯定就是n个点构成的凸包,贴个凸包模板就行。。。
PS:下面这个模板从NOI选手的资料中拿到的,特别短,用的是卷包裹法,不过貌似必须保证四点不共面,要不就会出错,具体去试试hdu 3662就知道了
所以,我还是打算自己实现个随机增量的写法。。。
代码:
#include <cmath>
#include <cstdio>
#include <set>
#include <map>
#include <vector>
#define NMax 1000
using namespace std;
struct point{
double x,y,z;
point(){}
point(double _x,double _y,double _z):x(_x),y(_y),z(_z){}
};
point operator-(const point &a, const point &b){
return point(a.x-b.x,a.y-b.y,a.z-b.z);
}
double operator*(const point &a,const point &b){
return a.x*b.x+a.y*b.y+a.z*b.z;
}
point operator^(const point &a,const point &b){
return point(a.y*b.z-a.z*b.y,a.z*b.x-a.x*b.z,a.x*b.y-a.y*b.x);
}
double Volcume(const point &a,const point &b,const point &c,const point &d){
return ((b-a)^(c-a))*(d-a);
}
set<pair<int,int> > Set;
vector<pair<int,pair<int,int> > > Faces;
point P[NMax];
int N;
void wrap(int a,int b){
if (Set.find(make_pair(a,b))==Set.end()){
int c=-1;
for (int i=0;i<N;i++)if (i!=a && i!=b){
if (c==-1 || Volcume(P[c],P[a],P[b],P[i])>0)
c=i;
}
if (c!=-1){
Faces.push_back(make_pair(a,make_pair(b,c)));
Set.insert(make_pair(a,b));
Set.insert(make_pair(b,c));
Set.insert(make_pair(c,a));
wrap(c,b);wrap(a,c);
}
}
}
double Sqr(double x)
{
return x*x;
}
double Dis(point p,point q)
{
return sqrt(Sqr(p.x-q.x)+Sqr(p.y-q.y)+Sqr(p.z-q.z));
}
double area(point p,point q,point r)
{
double a=Dis(p,q),b=Dis(p,r),c=Dis(q,r),t=(a+b+c)/2;
return sqrt(t*(t-a)*(t-b)*(t-c));
}
double ans;
int main()
{
scanf("%d",&N);
for (int i=0;i<N;i++)scanf("%lf%lf%lf",&P[i].x,&P[i].y,&P[i].z);
for (int i=1;i<N;i++)if (P[i].x<P[0].x)swap(P[0],P[i]);
for (int i=2;i<N;i++)if (
(P[i].x-P[0].x)*(P[1].y-P[0].y)>
(P[i].y-P[0].y)*(P[1].x-P[0].x))swap(P[1],P[i]);
wrap(0,1);
ans=0;
for(int i=0;i<(int)Faces.size();i++)
ans+=area(P[Faces[i].first],P[Faces[i].second.first],P[Faces[i].second.second]);
printf("%.3lf\n",ans);
return 0;
}
本文介绍了解决Aliens' armada攻击地球问题的凸包算法,通过计算包含所有战斗舰的最小面积来确定使用终极武器所需的最少能量。算法采用卷包裹法,确保四点不共面,以优化能量使用。
1482

被折叠的 条评论
为什么被折叠?



