luogu P4724 模板 三维凸包
LINK:三维凸包
一个非常古老的知识点。估计也没啥用。
大体上了解了过程 能背下来就背下来吧.
一个bf:暴力枚举三个点 此时只需要判断所有的点都在这个面的另外一侧就可以说明这个面是三维凸包上的面了。
一个问题 :多点共面问题。一个trick:可以利用扰动法然后 就可以解决这个问题了。
正解:\(n^2\)的增量法求三维凸包。
先加入三个不共线的点组成一个面(正反两面然后不断加入点。
然后考虑每一个点 删除这个点可以看到的面 然后边界与新加入的点连边即可。
具体理解看代码(我也有点迷。。
code
//#include<bits\stdc++.h>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<cctype>
#include<cstdlib>
#include<queue>
#include<deque>
#include<stack>
#include<vector>
#include<algorithm>
#include<utility>
#include<bitset>
#include<set>
#include<map>
#define ll long long
#define db double
#define INF 1000000000
#define ldb long double
#define pb push_back
#define put_(x) printf("%d ",x);
#define get(x) x=read()
#define gt(x) scanf("%d",&x)
#define gi(x) scanf("%lf",&x)
#define put(x) printf("%d\n",x)
#define putl(x) printf("%lld\n",x)
#define gc(a) scanf("%s",a+1)
#define rep(p,n,i) for(RE int i=p;i<=n;++i)
#define go(x) for(int i=lin[x],tn=ver[i];i;tn=ver[i=nex[i]])
#define fep(n,p,i) for(RE int i=n;i>=p;--i)
#define vep(p,n,i) for(RE int i=p;i<n;++i)
#define pii pair<int,int>
#define mk make_pair
#define RE register
#define P 1000000007
#define gf(x) scanf("%lf",&x)
#define pf(x) ((x)*(x))
#define uint unsigned long long
#define ui unsigned
#define EPS 1e-9
#define sq sqrt
#define mod 998244353
#define S second
#define F first
#define op(x) t[x].op
#define d(x) t[x].d
#define Set(a,v) memset(a,v,sizeof(a))
#define pf(x) ((x)*(x))
using namespace std;
char buf[1<<15],*fs,*ft;
inline char getc()
{
return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;
}
inline int read()
{
RE int x=0,f=1;RE char ch=getc();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getc();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getc();}
return x*f;
}
const int MAXN=2010;
int n,cnt;
int vis[MAXN][MAXN];
db ans=0;
db Rand(){return rand()/(db)RAND_MAX;}
db reps() {return (Rand()-0.5)*EPS;}
struct Vec
{
db x,y,z;
void shake(){x+=reps();y+=reps();z+=reps();}//扰动.
db len(){return sq(pf(x)+pf(y)+pf(z));}
Vec operator -(Vec a){return (Vec){x-a.x,y-a.y,z-a.z};}
Vec operator %(Vec a){return (Vec){y*a.z-z*a.y,z*a.x-x*a.z,x*a.y-y*a.x};}
db operator *(Vec a){return x*a.x+y*a.y+z*a.z;}
}a[MAXN];
typedef Vec point;
struct wy
{
int v[3];
Vec Nor(){return (a[v[1]]-a[v[0]])%(a[v[2]]-a[v[0]]);}
db area(){return Nor().len()/2.0;}
}f[MAXN],c[MAXN];
inline bool pd(wy c,Vec b){return ((b-a[c.v[0]])*c.Nor())>0;}
inline void Convex_3D()
{
f[cnt=1].v[0]=1;
f[cnt=1].v[1]=2;
f[cnt=1].v[2]=3;
f[cnt=2].v[0]=3;
f[cnt=2].v[1]=2;
f[cnt=2].v[2]=1;
rep(4,n,i)
{
int cc=0;
rep(1,cnt,j)
{
int ww=pd(f[j],a[i]);
if(!ww)c[++cc]=f[j];
rep(0,2,k)vis[f[j].v[k]][f[j].v[(k+1)%3]]=ww;
}
rep(1,cnt,j)
{
rep(0,2,k)
{
int x=f[j].v[k],y=f[j].v[(k+1)%3];
if(vis[x][y]&&!vis[y][x])
{
c[++cc].v[0]=x;c[cc].v[1]=y;c[cc].v[2]=i;
}
}
}
rep(1,cc,j)f[j]=c[j];
cnt=cc;
}
}
int main()
{
freopen("1.in","r",stdin);
gt(n);rep(1,n,i)scanf("%lf%lf%lf",&a[i].x,&a[i].y,&a[i].z),a[i].shake();
Convex_3D();rep(1,cnt,i)ans+=f[i].area();
printf("%.3lf",ans);return 0;
}
luogu P4724 模板 三维凸包的更多相关文章
- [Luogu4724][模板]三维凸包(增量构造法)
1.向量点积同二维,x1y1+x2y2+x3y3.向量叉积是行列式形式,(y1z2-z1y2,z1x2-x1z2,x1y2-y1x2). 2.增量构造法: 1)首先定义,一个平面由三个点唯一确定.一个 ...
- 题解-洛谷P4724 【模板】三维凸包
洛谷P4724 [模板]三维凸包 给出空间中 \(n\) 个点 \(p_i\),求凸包表面积. 数据范围:\(1\le n\le 2000\). 这篇题解因为是世界上最逊的人写的,所以也会有求凸包体积 ...
- Luogu P2742 模板-二维凸包
Luogu P2742 模板-二维凸包 之前写的实在是太蠢了.于是重新写了一个. 用 \(Graham\) 算法求凸包. 注意两个向量 \(a\times b>0\) 的意义是 \(b\) 在 ...
- Luogu 4724 三维凸包
Luogu 4724 三维凸包 增量法,维护当前凸包,每次加入一个点 \(P\) ,视其为点光源,将可见面删去,新增由"晨昏线"(分割棱)与 \(P\) 构成的平面. 注意每个平面 ...
- hdu4266(三维凸包模板题)
/*给出三维空间中的n个顶点,求解由这n个顶点构成的凸包表面的多边形个数. 增量法求解:首先任选4个点形成的一个四面体,然后每次新加一个点,分两种情况: 1> 在凸包内,则可以跳过 2> ...
- POJ3528 HDU3662 三维凸包模板
POJ3528 HDU3662 第一道题 给定若干点 求凸包的表面积,第二题 给定若干点就凸包的面数. 简单说一下三维凸包的求法,首先对于4个点假设不共面,确定了唯一四面体,对于一个新的点,若它不在四 ...
- POJ 2225 / ZOJ 1438 / UVA 1438 Asteroids --三维凸包,求多面体重心
题意: 两个凸多面体,可以任意摆放,最多贴着,问他们重心的最短距离. 解法: 由于给出的是凸多面体,先构出两个三维凸包,再求其重心,求重心仿照求三角形重心的方式,然后再求两个多面体的重心到每个多面体的 ...
- hdu4273Rescue(三维凸包重心)
链接 模板题已不叫题.. 三维凸包+凸包重心+点到平面距离(体积/点积) 体积-->混合积(先点乘再叉乘) #include <iostream> #include<cstd ...
- hdu 4273 2012长春赛区网络赛 三维凸包中心到最近面距离 ***
新模板 /* HDU 4273 Rescue 给一个三维凸包,求重心到表面的最短距离 模板题:三维凸包+多边形重心+点面距离 */ #include<stdio.h> #include&l ...
随机推荐
- 小书MybatisPlus第2篇-条件构造器的应用及总结
一.条件构造器Wrapper Mybatis Plus为我们提供了如下的一些条件构造器,我们可以利用它们实现查询条件.删除条件.更新条件的构造. 条件构造器用于给如下的Mapper方法传参,通常情况下 ...
- C# DataTable与Excel读取与导出
/// <summary> /// Excel->DataTable /// </summary> /// <param name="filePath&q ...
- Redis安装与运行讲解
第一步:安装Redis 打开网址:https://github.com/MicrosoftArchive/redis/releases 因为版本比较多,最新版已经是3.2.100,我们选择3.0.50 ...
- java 面向对象(二十一):属性的赋值顺序
* ①默认初始化 * ②显式初始化/⑤在代码块中赋值 * ③构造器中初始化 * ④有了对象以后,可以通过"对象.属性"或"对象.方法"的方式,进行赋值 * * ...
- A Great Alchemist 最详细的解题报告
题目来源:A Great Alchemist A Great Alchemist Time limit : 2sec / Stack limit : 256MB / Memory limit : 25 ...
- 深度学习论文翻译解析(十):Visualizing and Understanding Convolutional Networks
论文标题:Visualizing and Understanding Convolutional Networks 标题翻译:可视化和理解卷积网络 论文作者:Matthew D. Zeiler Ro ...
- sql多表语句
多条件查询条件判空 最优写法 3三表带条件查询
- (6)webpack使用babel插件的使用
为什么要使用babel插件? 首先要了解babel插件是干嘛的,随着js的语法规范发展,出现了越来越多的高级语法,但是使用webpack打包的时候,webpack并不能全部理解这些高级语法,需要我们使 ...
- Python Ethical Hacking - MAC Address & How to Change(2)
FUNCTIONS Set of instructions to carry out a task. Can take input, and return a result. Make the cod ...
- 代码Verify简介
序 对于开发者而言,编译代码和提交代码是必不可少的流程,同一个需求反复提交的情况也时常出现,那么怎么避免这种情况,且保证代码的质量,这就是Verify CI的目标.Verify表示认证验证的意思,结合 ...