Problem - 3662

  题意很简单,构造三维凸包,求凸包有多少个面。

代码如下:

 #include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath> using namespace std; const double EPS = 1e-;
const int N = ;
inline int sgn(double x) { return (x > EPS) - (x < -EPS);}
struct Point {
double x, y, z;
Point() {}
Point(double x, double y, double z) : x(x), y(y), z(z) {}
bool operator < (Point a) const {
if (sgn(x - a.x)) return x < a.x;
if (sgn(y - a.y)) return y < a.y;
return z < a.z;
}
bool operator == (Point a) const { return !sgn(x - a.x) && !sgn(y - a.y) && !sgn(z - a.z);}
Point operator + (Point a) { return Point(x + a.x, y + a.y, z + a.z);}
Point operator - (Point a) { return Point(x - a.x, y - a.y, z - a.z);}
Point operator * (double p) { return Point(x * p, y * p, z * p);}
Point operator / (double p) { return Point(x / p, y / p, z / p);}
} ;
inline double dot(Point a, Point b) { return a.x * b.x + a.y * b.y + a.z * b.z;}
inline double dot(Point o, Point a, Point b) { return dot(a - o, b - o);}
inline 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);}
inline Point cross(Point o, Point a, Point b) { return cross(a - o, b - o);}
inline double veclen(Point x) { return sqrt(dot(x, x));}
inline double area(Point o, Point a, Point b) { return veclen(cross(o, a, b)) / 2.0;}
inline double volume(Point o, Point a, Point b, Point c) { return dot(cross(o, a, b), c - o) / 6.0;} struct _3DCH{
Point pt[N];
int pcnt;
struct Face {
int a, b, c;
bool ok;
Face() {}
Face(int a, int b, int c) : a(a), b(b), c(c) { ok = true;}
} fc[N << ];
int fcnt;
int fid[N][N]; bool outside(int p, int a, int b, int c) { return sgn(volume(pt[a], pt[b], pt[c], pt[p])) < ;}
bool outside(int p, int f) { return outside(p, fc[f].a, fc[f].b, fc[f].c);}
void addface(int a, int b, int c, int d) {
if (outside(d, a, b, c)) fc[fcnt] = Face(c, b, a), fid[c][b] = fid[b][a] = fid[a][c] = fcnt++;
else fc[fcnt] = Face(a, b, c), fid[a][b] = fid[b][c] = fid[c][a] = fcnt++;
} bool dfs(int p, int f) {
if (!fc[f].ok) return true;
int a = fc[f].a, b = fc[f].b, c = fc[f].c;
if (outside(p, a, b, c)) {
fc[f].ok = false;
if (!dfs(p, fid[b][a])) addface(p, a, b, c);
if (!dfs(p, fid[c][b])) addface(p, b, c, a);
if (!dfs(p, fid[a][c])) addface(p, c, a, b);
return true;
}
return false;
}
void build() {
bool ok;
fcnt = ;
sort(pt, pt + pcnt);
pcnt = unique(pt, pt + pcnt) - pt;
ok = false;
for (int i = ; i < pcnt; i++) {
if (sgn(area(pt[], pt[], pt[i]))) {
ok = true;
swap(pt[i], pt[]);
break;
}
}
if (!ok) return ;
ok = false;
for (int i = ; i < pcnt; i++) {
if (sgn(volume(pt[], pt[], pt[], pt[i]))) {
ok = true;
swap(pt[i], pt[]);
break;
}
}
if (!ok) return ;
addface(, , , );
addface(, , , );
addface(, , , );
addface(, , , );
for (int i = ; i < pcnt; i++) {
for (int j = fcnt - ; j >= ; j--) {
if (outside(i, j)) {
dfs(i, j);
break;
}
}
}
int sz = fcnt;
fcnt = ;
for (int i = ; i < sz; i++) if (fc[i].ok) fc[fcnt++] = fc[i];
}
double facearea() {
double ret = 0.0;
for (int i = ; i < fcnt; i++) ret += area(pt[fc[i].a], pt[fc[i].b], pt[fc[i].c]);
return ret;
}
bool same(int i, int j) {
int a = fc[i].a, b = fc[i].b, c = fc[i].c;
if (sgn(volume(pt[a], pt[b], pt[c], pt[fc[j].a]))) return false;
if (sgn(volume(pt[a], pt[b], pt[c], pt[fc[j].b]))) return false;
if (sgn(volume(pt[a], pt[b], pt[c], pt[fc[j].c]))) return false;
return true;
}
int facecnt() {
int cnt = ;
for (int i = ; i < fcnt; i++) {
bool ok = true;
for (int j = ; j < i; j++) {
if (same(i, j)) {
ok = false;
break;
}
}
if (ok) cnt++;
}
return cnt;
}
} ch; int main() {
// freopen("in", "r", stdin);
int n;
double x, y, z;
while (~scanf("%d", &ch.pcnt)) {
for (int i = ; i < ch.pcnt; i++) {
scanf("%lf%lf%lf", &x, &y, &z);
ch.pt[i] = Point(x, y, z);
}
ch.build();
// printf("%.3f\n", ch.facearea());
printf("%d\n", ch.facecnt());
}
return ;
}

  三维凸包还是挺简单的,不用抄模板也能敲出来。不过,还不熟练,敲了接近一个钟。

——written by Lyon

hdu 3662 3D Convex Hull的更多相关文章

  1. 【HDU 3662】3D Convex Hull

    http://acm.hdu.edu.cn/showproblem.php?pid=3662 求给定空间中的点的三维凸包上有多少个面. 用增量法,不断加入点,把新加的点能看到的面都删掉,不能看到的面与 ...

  2. poj 3528 Ultimate Weapon (3D Convex Hull)

    3528 -- Ultimate Weapon 一道三维凸包的题目,题目要求求出三维凸包的表面积.看懂了网上的三维凸包的代码以后,自己写的代码,跟网上的模板有所不同.调了一个晚上,结果发现错的只是数组 ...

  3. 2D Convex Hulls and Extreme Points( Convex Hull Algorithms) CGAL 4.13 -User Manual

    1 Introduction A subset S⊆R2 is convex if for any two points p and q in the set the line segment wit ...

  4. 凸包(Convex Hull)构造算法——Graham扫描法

    凸包(Convex Hull) 在图形学中,凸包是一个非常重要的概念.简明的说,在平面中给出N个点,找出一个由其中某些点作为顶点组成的凸多边形,恰好能围住所有的N个点. 这十分像是在一块木板上钉了N个 ...

  5. Convex Hull 实现理论+自制Python代码

    Convex Hull 概述 计算n维欧式空间散点集的凸包,有很多的方法.但是如果要实现快速运算则其难点在于:如何快速判断散点集的成员是否是在凸集的内部.如果可以简化判断的运算过程,则可以极大简化迭代 ...

  6. OpenCV入门之寻找图像的凸包(convex hull)

    介绍   凸包(Convex Hull)是一个计算几何(图形学)中的概念,它的严格的数学定义为:在一个向量空间V中,对于给定集合X,所有包含X的凸集的交集S被称为X的凸包.   在图像处理过程中,我们 ...

  7. Monotone Chain Convex Hull(单调链凸包)

    Monotone Chain Convex Hull(单调链凸包)算法伪代码: //输入:一个在平面上的点集P //点集 P 按 先x后y 的递增排序 //m 表示共a[i=0...m]个点,ans为 ...

  8. convex hull

    1 什么是convex hull 就是凸包,是计算几何中的一个概念,计算几何是计算机图形学的基础之一. 对于二维平面来说是这样的:对于二维平面上的点集,凸包是位于最外层的点构成的包围其它所有的点的凸多 ...

  9. opencv::凸包-Convex Hull

    概念介绍 什么是凸包(Convex Hull),在一个多变形边缘或者内部任意两个点的连线都包含在多边形边界或者内部. 正式定义:包含点集合S中所有点的最小凸多边形称为凸包 Graham扫描算法 首先选 ...

随机推荐

  1. jS生成二叉树,二叉树的遍历,查找以及插入

    js递归,二叉树的操作 //递归算法n次幂 function foo(n) { if (n == 1) { return 1; } else { return n * foo(n - 1); } } ...

  2. ES6中async和await说明和用法

    昨天看了一篇vue的教程,作者用async/ await来发送异步请求,从服务端获取数据,代码很简洁,同时async/await 已经被标准化,是时候学习一下了. 先说一下async的用法,它作为一个 ...

  3. day18 16.dbcp连接池使用介绍

    package cn.itcast.datasource; import java.io.FileInputStream; import java.sql.Connection; import jav ...

  4. 【weex】publishTask

    这个小项目还挺有意思的,是一个效果取快递的项目 我们看下效果 放博客的github地址:https://github.com/xiaomaer/publishTask 我们来看下代码,这几个页面运行的 ...

  5. 请自行检查是否安装VC9运行库??

    phpStudy是一款PHP调试环境的程序集成包,该程序包集成最新的Apache+PHP+MySQL+phpMyAdmin+ZendOptimizer,一次性安装,无须配置即可使用,是非常方便.好用的 ...

  6. 全面系统Python3入门+进阶课程

    全面系统Python3入门+进阶课程 整个课程都看完了,这个课程的分享可以往下看,下面有链接,之前做java开发也做了一些年头,也分享下自己看这个视频的感受,单论单个知识点课程本身没问题,大家看的时候 ...

  7. 2-2 Numpy-矩阵

    # !usr/bin/env python # Author:@vilicute import numpy as np # 矩阵的创建 matr1 = np.mat("4 2 3;4 5 6 ...

  8. [java]java构造器 标签: java面向对象 2017-06-11 11:16 195人阅读 评论(12)

    构造器这个概念,各种语言都有出现,虽然为了考试或者其他学了好多遍,但是自己一直不能理解这个概念,前几天又学了一遍,突然就明白了,下面随小编来一起学习一下吧. 什么是构造器? 在类别基础的面向对象程序设 ...

  9. 【水滴石穿】rn_statusbar

    先放项目地址https://github.com/hezhii/rn_statusbar 来看一下效果 咩有感觉很怎么样,看代码 根入口文件 //index.js //看代码我们知道入口是app.js ...

  10. SQLServer —— 变量的使用

    一.局部变量的定义与赋值 定义语法: -- 声明一个局部变量 DECLARE @变量名 数据类型 -- 声明多个局部变量 DECLARE @变量名1 数据类型1, @变量名2 数据类型2 赋值语法: ...