欢迎访问~原文出处——博客园-zhouzhendong

去博客园看该题解


题目传送门 - BZOJ1209


题目概括

  给出立体的n个点。求三维凸包面积。


题解

  增量法,看了一天,还是没有完全懂。

  上板子!


代码

#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <ctime>
using namespace std;
const double Eps=1e-8;
const int N=100+5;
int Dcmp(double x){
if (fabs(x)<Eps)
return 0;
return x<0?-1:1;
}
struct Point{
double x,y,z;
Point (){}
Point (double x_,double y_,double z_){
x=x_,y=y_,z=z_;
}
}P[N],p[N];
Point operator - (Point a,Point b){
return Point(a.x-b.x,a.y-b.y,a.z-b.z);
}
Point operator + (Point a,Point b){
return Point(a.x+b.x,a.y+b.y,a.z+b.z);
}
Point operator * (Point a,double x){
return Point(a.x*x,a.y*x,a.z*x);
}
Point operator / (Point a,double x){
return Point(a.x/x,a.y/x,a.z/x);
}
Point cross(Point a,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);
}
Point cross(Point a,Point b,Point c){
return cross(b-a,c-a);
}
double Dot(Point a,Point b){
return a.x*b.x+a.y*b.y+a.z*b.z;
}
double Length(Point P){
return sqrt(Dot(P,P));
}
double rand01(){
return (double)rand()/(double)RAND_MAX;
}
double randEps(){
return (rand01()-0.5)*Eps;
}
Point add_noise(Point P){
return Point(P.x+randEps(),P.y+randEps(),P.z+randEps());
}
struct Face{
int v[3];
Face(){}
Face(int a,int b,int c){
v[0]=a,v[1]=b,v[2]=c;
}
Point Normal(Point *P){
return cross(P[v[0]],P[v[1]],P[v[2]]);
}
int CanSee(Point *P,int i){
return Dot(P[i]-P[v[0]],Normal(P))>0?1:0;
}
};
struct ConvexHull{
vector <Face> cur;
bool vis[N][N];
void Increment(Point *P,int n){
vector <Face> next;
memset(vis,0,sizeof vis);
for (int i=1;i<=n;i++)
P[i]=add_noise(P[i]);
cur.clear();
cur.push_back(Face(1,2,3));
cur.push_back(Face(3,2,1));
for (int i=4;i<=n;i++){
next.clear();
for (int j=0;j<cur.size();j++){
Face F=cur[j];
int res=F.CanSee(P,i);
if (!res)
next.push_back(F);
for (int k=0;k<3;k++)
vis[F.v[k]][F.v[(k+1)%3]]=res;
}
for (int j=0;j<cur.size();j++)
for (int k=0;k<3;k++){
int a=cur[j].v[k],b=cur[j].v[(k+1)%3];
if (vis[a][b]&&!vis[b][a])
next.push_back(Face(a,b,i));
}
cur=next;
}
}
double Area(Point a,Point b,Point c){
return 0.5*Length(cross(a,b,c));
}
double Area(Face F,Point *P){
return Area(P[F.v[0]],P[F.v[1]],P[F.v[2]]);
}
double Area(Point *P){
double Answer=0;
for (int i=0;i<cur.size();i++)
Answer+=Area(cur[i],P);
return Answer;
}
}Hull;
int n;
int main(){
scanf("%d",&n);
for (int i=1;i<=n;i++){
scanf("%lf%lf%lf",&P[i].x,&P[i].y,&P[i].z);
p[i]=P[i];
}
Hull.Increment(p,n);
printf("%.6lf",Hull.Area(P));
return 0;
}

  

BZOJ1209 [HNOI2004]最佳包裹 三维凸包 计算几何的更多相关文章

  1. bzoj 1209: [HNOI2004]最佳包裹 三维凸包

    1209: [HNOI2004]最佳包裹 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 160  Solved: 58[Submit][Status] ...

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

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

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

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

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

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

  5. 洛谷P4502 [ZJOI2018]保镖(计算几何+三维凸包)

    题面 传送门 题解 我对计蒜几盒一无所知 顺便\(xzy\)巨巨好强 前置芝士 三维凸包 啥?你不会三维凸包?快去把板子写了->这里 欧拉公式 \[V-E+F=2\] \(V:vertex\)顶 ...

  6. Hnoi2004 金属包裹

    传送门 三维凸包模板题……只是听了听计算几何的课之后心血来潮想写的…… 我的做法很无脑是吧……暴力枚举三个点组成的三角形,然后枚举剩下的点,判断其余点是否都在这个三角形的同一侧,是的话则说明这个三角形 ...

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

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

  8. hdu4273Rescue(三维凸包重心)

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

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

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

随机推荐

  1. OptionParser命令参数介绍及使用

    使用optionParse解析命令行参数分以下几个步骤: 创建parser实例 使用add_option添加我们要处理的命令行参数 得到解析sys.argv后的options对象,查看用户的输入 代码 ...

  2. SAP笔记---非-现存任务/请求XXX上的请求锁定

    不管在SAP中的哪个系统在点击修改程序时都有可能出现以下图中的报错: 已找到解决办法,步骤如下: 1,se11中查看tlock表找到以上提到的请求号记录: 2,进入se16n,输入请求号,在事务代码输 ...

  3. yolov3实践(一)

    很多博友看了我的第一篇博客yolo类检测算法解析——yolo v3,对其有了一定的认识和了解,但是并没有贴出代码和运行效果,略显苍白.因此在把篇博客理论的基础上,造就了第一篇实践文章,也就是本文.只要 ...

  4. 设置PHPStorm 注释

    /** * Desc: xxx#if (${NAME}) * Class: ${NAME}#end#if (${NAMESPACE}) * Package: ${NAMESPACE}#end * Us ...

  5. 运维数据库平台~inception审核规则详解

    ---恢复内容开始--- 一 简介:这次我们来介绍最核心的审核功能 二 讲解:简单来说 inception就是mysql的二次过滤,何谓二次过滤,我们知道,mysql本身都有自己的审核规则,为业界所通 ...

  6. Android ROM资源文件存放位置

    位于目录:framework/core/res/res /frameworks/base/core/res/res/values/public.xml 上面的文件中公开了上层(也就是第三方应用或者系统 ...

  7. Java打印M图形(二维数组)——(九)

    对于平面图形输出集合图形与数字组合的,用二维数组.先在Excel表格中分析一下,找到简单的规律.二维数组的行数为行高,列数为最后一个数大小. 对于减小再增大再减小再增大的,可以用一个boolean标志 ...

  8. Spring使用RMI进行远程方法调用

    (1).我新建了三个项目,SpringRmiApi(存放提供者和消费者共有的xx,例如实体类以及服务接口等等).SpringRmiService(服务提供者).SpringRmiProvider(服务 ...

  9. [转]GDB-----1.GDB概述

    作者: liigo原文链接: http://blog.csdn.net/liigo/archive/2006/01/17/582231.aspx 1.前言 本文写给主要工作在Windows操作系统下而 ...

  10. Linux系统无线网卡的安装【转】

    转自:http://www.linuxidc.com/Linux/2013-03/81473.htm 现在的很多的可移动无线网卡都是usb接口的,把这种网卡应用到windows操作系统上是很容易就能起 ...