1964: hull 三维凸包

Time Limit: 1 Sec  Memory Limit: 64 MB
Submit: 54  Solved: 39
[Submit][Status][Discuss]

Description

三维凸包问题是一个基础的三维计算几何问题,不过这次你只需要做一个简单版的三维凸包问题就行了。

Input

输入数据一共有若干行,每行三个整数,表示一个点的坐标。点的个数为五个。

Output

输出一个实数,保留两位小数,表示三维凸包的体积。

Sample Input

0 0 0
2 0 0
0 2 0
2 2 0
1 1 1

Sample Output

1.33

HINT

对于所有数据,坐标范围在[0,100]*[0,100]*[0,100]。

  直接水过,不过网上的三维凸包的标程一个比一个不靠谱,由一组数据拍出来,加上我的程序,三个程序三个答案。整个人都不好了。

  枚举一个面,使得剩下两个点与这条面组成四面体的有向体积符号不同,则两点在面的两侧,计算即可。

  四面体的计算公式是三个向量组成的矩阵行列式的1/6.

  这是居然我的第一个三维算几题。

  另外,这个方法的正确性我还是比较怀疑,因为存在数据是他和网上的三维算几模板矛盾,虽然大部分可以看出是网上的程序的问题,但是居然他与我自己写的版有矛盾,就姑且把它当成骗分暴力吧。(最后有三维凸包程序)

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<cmath>
using namespace std;
#define MAXN 10
typedef double real;
struct point
{
real x,y,z;
point(real x,real y,real z):x(x),y(y),z(z){}
point(){}
void read()
{
scanf("%lf %lf %lf",&x,&y,&z);
}
}pl[MAXN];;
real area(point p1,point p2,point p3)
{
return (p1.x*p2.y*p3.z + p1.z*p2.x*p3.y + p1.y*p2.z*p3.x
-p1.x*p2.z*p3.y - p1.z*p2.y*p3.x - p1.y*p2.x*p3.z)/;
}
point operator -(point p1,point p2)
{
return point(p2.x-p1.x,p2.y-p1.y,p2.z-p1.z);
}
typedef point line; bool vis[MAXN];
int main()
{
freopen("input.txt","r",stdin);
for (int i=;i<;i++)
{
pl[i].read();
}
// printf("%.2lf\n",area(pl[1]-pl[0],pl[2]-pl[0],pl[3]-pl[0]));
real ans=;
real s1,s2,s3;
for (int a=;a<;a++)
{
vis[a]=true;
for (int b=;b<;b++)
{
if (vis[b])continue;
vis[b]=true;
for (int c=;c<;c++)
{
if (vis[c])continue;
vis[c]=true;
for (int d=;d<;d++)
{
if (vis[d])continue;
vis[d]=true;
for (int e=;e<;e++)
{
if (vis[e])continue;
vis[e]=true;
s3=abs(s1=area(pl[c]-pl[a],pl[b]-pl[a],pl[d]-pl[a]))+abs(s2=area(pl[c]-pl[a],pl[b]-pl[a],pl[e]-pl[a]));
if (s1*s2>)
{
vis[e]=false;continue;
}
if (s1== && s2==)
{
vis[e]=false;continue;
}
ans=max(ans,s3);
vis[e]=false;
}
vis[d]=false;
}
vis[c]=false;
}
vis[b]=false;
}
vis[a]=false;
}
printf("%.2lf\n",ans);
}
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<assert.h>
#include<vector>
using namespace std;
#define MAXN 120
#define eps 1e-8
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=;
while (~pl[n++].read());
n--;
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().volume(point(,,))/;
}
printf("%.2lf\n",abs(ans));
}

bzoj 1964: hull 三维凸包 计算几何的更多相关文章

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

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

  2. [BZOJ1964]hull 三维凸包:计算几何

    分析 发现自己并不会计算几何. 所以先引用一下这位dalao的博客. 二维平面四个点求凸包面积->任选三个点面积之和/2 三维平面五个点求凸包体积->任选四个点体积之和/2 二维平面三个点 ...

  3. bzoj1964: hull 三维凸包

    传送门 二维平面四个点求凸包面积->任选三个点面积之和/2 三维平面五个点求凸包体积->任选四个点体积之和/2 二维平面三个点面积->二个二维向量行列式值的绝对值/2 三维平面四个点 ...

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

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

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

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

  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. 设置background属性使用selector的时候内置?attr报错的解决方案

    当我们设置background属性的时候可以设置background="@color/black" 也可以设置 background="@drawable/selecto ...

  2. 监控Linux内存使用情况

    cat mem.sh#!/bin/bashIP=`ifconfig | grep 'inet ' | grep -v '127.0.0.1' | awk -F ' ' '{print $2}'| aw ...

  3. 四种方式写按钮点击事件和Android 中常用的布局

    1.匿名内部类的方式 2.创建一个类实现onClickListener,实现onClick方法,设置控件点击时传一个类的对象 3.让当前类实现onClickListener,设置控件点击事件时传递一个 ...

  4. magento搜索属性值的设置方法

    前台特性(Frontend Properties)在快速搜索中应用(Use in quick search) - 开启此选项,在客户使用Header中的 搜索功能时Magento将搜索所有产品这个At ...

  5. javaweb 中的乱码问题

    一.post 方式 首先我们看下面一段代码,在该HTML中我们指定的编码为“UTF-8”,如图所示. 在该代码中,我们将表单数据提交给ParamServlet 处理 servlet 会将接收到的数据打 ...

  6. 3.redis.3.2 下载,安装、配置、使用、集群主从创建 - 3

    当然,集群最主要的就是配置文件: 简单配置如下, port 7001 bind 127.0.0.1 databases 16 appendonly yes appendfilename "a ...

  7. Entity Framework 使用sql语句分页(查询视图)

    1.查询视图 //3.查询视图 var sql = @" SELECT D.* FROM ( SELECT ROW_NUMBER() OVER ( ORDER BY TestView.B_M ...

  8. Solr4.7新建core

    Solr里面的core就像数据库里面的一个表,用来管理索引和相关配置. 一. 使用示例core 下载的solr完整包里面solr-4.7.0\example\multicore这个文件夹下面有2个示例 ...

  9. asp.net:录入数据库的中文变问号

    表格是可以接受中文的: 类型也是nvarchar的: 还是出现写中文变问号?? 这时候请加入转义大写N: 如: 原查询语句:insert into table1(name)  values('蜘蛛侠' ...

  10. 关于web项目中中文乱码问题的总结

    关于post和get的中文乱码处理 get: (1)转码:String username=request.getParameter("username");       Strin ...