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 ...
随机推荐
- 小程序被冻结,忘记原始ID,如何找回?
登录成功,提示被冻结,选择"账号找回": 阅读须知:账号类型选择“小程序”,需要输入小程序的原始ID,此时已经不记得了~~ 微信:搜索 “ 公众平台安全助手 ” 并关注 点击查 ...
- 007.Nginx虚拟主机
一 虚拟主机 1.1 虚拟主机概念 对于Nginx而言,每一个虚拟主机相当于一个在同一台服务器中却相互独立的站点,从而实现一台主机对外提供多个 web 服务,每个虚拟主机之间是独立的,互不影响的. 1 ...
- windows下的包管理器scoop
scoop(传送门) 安装 scoop是一个类似于linux下apt之类包管理器 安装scoop(Powershell 3+ and .NET Framework 4.5+) iex (new-ob ...
- Ubuntu下编译安装postgreSQL 10.5
Ubuntu下编译安装postgreSQL 10.5 ubuntu 16.04 LTS系统postgreSQL 10.5 安装包准备 1.从PostgreSQL官网下载PostgreSQL的安装包 安 ...
- scala 数据结构(十一):流 Stream、视图 View、线程安全的集合、并行集合
1 流 Stream stream是一个集合.这个集合,可以用于存放无穷多个元素,但是这无穷个元素并不会一次性生产出来,而是需要用到多大的区间,就会动态的生产,末尾元素遵循lazy规则(即:要使用结果 ...
- Linux04 /创建虚拟环境、在linux环境运行Python项目
Linux04 /创建虚拟环境.在linux环境运行Python项目 目录 Linux04 /创建虚拟环境.在linux环境运行Python项目 1. 大体流程 2. linux环境安装python3 ...
- Python之堡垒机
本节内容 项目实战:运维堡垒机开发 前景介绍 到目前为止,很多公司对堡垒机依然不太感冒,其实是没有充分认识到堡垒机在IT管理中的重要作用的,很多人觉得,堡垒机就是跳板机,其实这个认识是不全面的,跳板功 ...
- Ant Design Pro 学习笔记:数据流向
在讲这个问题之前,有一个问题应当讲一下: Ant Design Pro / umi / dva 是什么关系? 首先是 umi / dva 的关系. umi 是一个基于路由的 react 开发框架. d ...
- TLV通信协议
基础 TLV协议是BER编码的一种,全称是Tag.length.value.该协议简单高效,能适用于各种通信场景,且具有良好的可扩展性.TLV协议的基本格式如下: 其中,Tag占2个字节,是报文的唯一 ...
- 如何将elementUI 表格(el-table)和分页器(el-pagination)连接起来
el-table表格的代码: <template> <el-table :data="tableData" style="width: 100%&quo ...