1209: [HNOI2004]最佳包裹

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 160  Solved: 58
[Submit][Status][Discuss]

Description

H
公司生产了一种金属制品,是由一些笔直的金属条支撑起来的,金属条和别的金属条在交点上被焊接在了一起。现在由于美观需要,在这个产品用一层特殊的材料包
裹起来。公司为了节约成本,希望消耗的材料最少(不计裁剪时的边角料的损失)。你的程序需要根据给定的输入,给出符合题意的输出:
输入包括该产品的顶点的个数,以及所有顶点的坐标; 你需要根据输入的计算出包裹这个产品所需要的材料的最小面积。
结果要求精确到小数点后第六位。(四舍五入)

Input

第1行是一个整数n(4 <= n <= 100),表示顶点的个数;第2行到第n+1行,每行是3个实数xi,yi,zi,表示第i个顶点的坐标。每个顶点的位置各不相同。

Output

输出只有一个实数,表示包裹一个该产品所需的材料面积的最小值。

Sample Input

4
0 0 0
1 0 0
0 1 0
0 0 1 说明:该输入示例中共有4个点,可参见后面的图示。

Sample Output

2.366025

HINT

  这道题算是三维凸包的模板题吧,话说网上的三维凸包的教程中判三点共线,四点共面的方法确实有些复杂,经过idy博客的启发,其实在做凸包前对每个点加一遍噪音就行了。如果一个点可以看见当前一个面,那么这个面就会被删除,其表现就是有向体积为负数,删除一个面的同时,删除这个面的三条边(也是有向的)最有扫一遍观察哪些边的反向边不存在,然后将他们的反向边与当前加的点一同构成新的凸包。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<assert.h>
#include<vector>
using namespace std;
#define MAXN 120
#define eps 1e-11
typedef double real;
inline int sgn(real x)
{
if (abs(x)<eps)return ;
return x<?-:;
}
struct point
{
real x,y,z;
point(real x,real y,real z):x(x),y(y),z(z){}
point(){}
int read()
{
return scanf("%lf %lf %lf\n",&x,&y,&z);
}
void noise()
{
x+=(real)(rand()%-)/*eps;
y+=(real)(rand()%-)/*eps;
z+=(real)(rand()%-)/*eps;
}
real len()
{
return sqrt(x*x+y*y+z*z);
}
};
typedef point vect;
struct line
{
point ps;
real x,y,z;
line(){}
line(point p1,point p2)
{
ps=p1;
x=p2.x-p1.x;
y=p2.y-p1.y;
z=p2.z-p1.z;
}
line(point ps,real x,real y,real z):ps(ps),x(x),y(y),z(z){}
};
vect xmul(line l1,line l2)
{
return vect(l1.y*l2.z-l1.z*l2.y,l1.z*l2.x-l1.x*l2.z,l1.x*l2.y-l1.y*l2.x);
}
real volume(line l1,line l2,line l3)
{
return + l1.x*l2.y*l3.z - l1.x*l2.z*l3.y
- l1.y*l2.x*l3.z + l1.y*l2.z*l3.x
+ l1.z*l2.x*l3.y - l1.z*l2.y*l3.x;
}
//+1 2 3
//-1 3 2
//-2 1 3
//+2 3 1
//+3 1 2
//-3 2 1
struct surface
{
point ps;
real x1,y1,z1;
real x2,y2,z2;
surface(){}
surface(point p1,point p2,point p3)
{
ps=p1;
x1=p2.x-p1.x,y1=p2.y-p1.y,z1=p2.z-p1.z;
x2=p3.x-p1.x,y2=p3.y-p1.y,z2=p3.z-p1.z;
}
real volume(point pt)
{
return ::volume(line(ps,pt),line(ps,x1,y1,z1),line(ps,x2,y2,z2));
}
vect nvect()
{
return xmul(line(ps,x1,y1,z1),line(ps,x2,y2,z2));
}
void reverse()
{
swap(x1,x2);
swap(y1,y2);
swap(z1,z2);
}
};
point pl[MAXN];
struct face
{
int pt[];
face(int x,int y,int z)
{
pt[]=x;pt[]=y;pt[]=z;
}
surface ToSurface()
{
return surface(pl[pt[]],pl[pt[]],pl[pt[]]);
}
void print()
{
printf("Face:%d %d %d\n",pt[],pt[],pt[]);
}
};
vector<face> cc;
vector<pair<int,int> > chs;
bool status[MAXN][MAXN];
int main()
{
freopen("input.txt","r",stdin);
int n;
scanf("%d",&n);
for (int i=;i<n;i++)
pl[i].read();
for (int i=;i<n;i++)
pl[i].noise();
/* for (int i=0;i<n;i++)
swap(pl[rand()%n],pl[rand()%n]);*/
cc.push_back(face(,,));
cc.push_back(face(,,));
for (int i=;i<;i++)
status[i][(i+)%]=true;
for (int i=;i<;i++)
status[i%][i-]=true;
for (int i=;i<n;i++)
{
//for (int j=0;j<cc.size();j++)cc[j].print(); printf("\n");
chs.clear();
for (int j=;j<cc.size();j++)
{
if (cc[j].ToSurface().volume(pl[i])<)
{
for (int k=;k<;k++)
{
status[cc[j].pt[k]][cc[j].pt[(k+)%]]=false;
chs.push_back(make_pair(cc[j].pt[k],cc[j].pt[(k+)%]));
}
swap(cc[j],cc[cc.size()-]);
cc.pop_back();
j--;
}
}
for (int j=;j<chs.size();j++)
{
if (!status[chs[j].first][chs[j].second] && status[chs[j].second][chs[j].first])continue;
chs[j]=chs[chs.size()-];
j--;
chs.pop_back();
}
for (int j=;j<chs.size();j++)
{
cc.push_back(face(i,chs[j].first,chs[j].second));
status[i][chs[j].first]=status[chs[j].first][chs[j].second]=status[chs[j].second][i]=true;
}
for (int j=;j<n;j++)
for (int k=;k<n;k++)
assert(!(status[j][k]^status[k][j]));
}
//for (int j=0;j<cc.size();j++)cc[j].print(); printf("\n");
real ans=;
for (int i=;i<cc.size();i++)
ans+=cc[i].ToSurface().nvect().len()/;
printf("%.6lf\n",abs(ans));
}

bzoj 1209: [HNOI2004]最佳包裹 三维凸包的更多相关文章

  1. BZOJ1209 [HNOI2004]最佳包裹 三维凸包 计算几何

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1209 题目概括 给出立体的n个点.求三维凸包面积. 题解 增量法,看了一天,还是没有完全懂. 上板 ...

  2. 洛谷P2287 [HNOI2004]最佳包裹(三维凸包)

    题面 传送门 题解 左转板子,调个精度就能\(A\)了 //minamoto #include<bits/stdc++.h> #define R register #define fp(i ...

  3. BZOJ1209 最佳包裹 (三维凸包 增量法)

    题意 求三维凸包的表面积. N≤100N\le100N≤100 题解 暴力往当前的凸包里加点.O(n2)O(n^2)O(n2).题解详见大佬博客 扰动函数shakeshakeshake是为了避免四点共 ...

  4. bzoj 1964: hull 三维凸包 计算几何

    1964: hull 三维凸包 Time Limit: 1 Sec  Memory Limit: 64 MBSubmit: 54  Solved: 39[Submit][Status][Discuss ...

  5. bzoj 1209

    三维凸包裸题. 1.通过volume计算有向体积,判断点与面的位置关系. 2.噪声 /********************************************************* ...

  6. POJ 2225 / ZOJ 1438 / UVA 1438 Asteroids --三维凸包,求多面体重心

    题意: 两个凸多面体,可以任意摆放,最多贴着,问他们重心的最短距离. 解法: 由于给出的是凸多面体,先构出两个三维凸包,再求其重心,求重心仿照求三角形重心的方式,然后再求两个多面体的重心到每个多面体的 ...

  7. hdu4273Rescue(三维凸包重心)

    链接 模板题已不叫题.. 三维凸包+凸包重心+点到平面距离(体积/点积)  体积-->混合积(先点乘再叉乘) #include <iostream> #include<cstd ...

  8. hdu4449Building Design(三维凸包+平面旋转)

    链接 看了几小时也没看懂代码表示的何意..无奈下来问问考研舍友. 还是考研舍友比较靠谱,分分钟解决了我的疑问. 可能三维的东西在纸面上真的不好表示,网上没有形象的题解,只有简单"明了&quo ...

  9. hdu 4273 2012长春赛区网络赛 三维凸包中心到最近面距离 ***

    新模板 /* HDU 4273 Rescue 给一个三维凸包,求重心到表面的最短距离 模板题:三维凸包+多边形重心+点面距离 */ #include<stdio.h> #include&l ...

随机推荐

  1. apache solr简单搭建

    首先,下载位置是:http://lucene.apache.org/solr/downloads.html 官网的学习资料:http://lucene.apache.org/solr/quicksta ...

  2. [Form Builder]:CREATE_GROUP Built-in

    Description  Creates a non-query record group with the given name. The new record group has no colum ...

  3. 1.Linux系统(CenntOS)固定IP的设定

    首先:我们配置一个临时的固定的固定ip,作用是让我们用其他的shell工具连接虚拟机 ifconfig eth0 192.168.10.168 在主机用ping命令查询连通后再进行下一步 ping 1 ...

  4. 【S】【S】【S】一大波前端干货整合(一)

      前端交流站点 大前端       http://www.daqianduan.com/ V2EX       http://www.v2ex.com/ W3cplus    http://www. ...

  5. Asp.net 上传文件小叙(修改FileUpload显示文字等)

    想要在asp.net网站上上传文件就得用到FileUpload,可是这个控件中“浏览”没法修改,可以使用html中<input type="file" 来解决该问题. 首先页 ...

  6. SqlServer2008误操作数据(delete或者update)后恢复数据

    实际工作中,有时会直接在数据库中操作数据,比如对数据进行delete或者update操作,当进行这些操作的时候,如果没有加上where条件或者where条件不合理,那么导致的结果可想而知,如果操作的又 ...

  7. 百度地图API调用实例之地址标注与位置显示

    之前弄了个谷歌地图API标注的调用实例,后来要求改成百度地图. 感谢主,通过网上资料(百度地图API,百度地图API详解之地图标注)收集及研究, 终于把百度地图标注和显示功能实现出来了,具体实现方法如 ...

  8. Java之反射的应用

      package com.zheges; import java.util.Date; public class Customer {//JavaBean 对象 private String nam ...

  9. Deep Learning 学习随记(三)续 Softmax regression练习

    上一篇讲的Softmax regression,当时时间不够,没把练习做完.这几天学车有点累,又特别想动动手自己写写matlab代码 所以等到了现在,这篇文章就当做上一篇的续吧. 回顾: 上一篇最后给 ...

  10. iOS测试一段代码的运行时间

    王刚韧 23:19:26测试一段代码的运行时间 测试一段代码运行花了多久: NSDate* tmpStartData = [NSDate date] ;<#代码#> double delt ...