POJ 3528 & POJ 2974 三维凸包

题意:给出n个点,求三维凸包及其表面积。

下面这个模板从NOI选手的资料中拿到的,特别短,用的是卷包裹法,不过貌似必须保证四点不共面,要不就会出错。

POJ 3528

#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<set>
#include<vector>
#include<map>
#include<cmath>
#define maxn 1000
using namespace std;
struct point
{
    double x,y,z;
    point() {}
    point(double _x,double _y,double _z):x(_x),y(_y),z(_z) {}
};
point operator-(const point &a,const point &b)
{
    return point(a.x-b.x,a.y-b.y,a.z-b.z);
}
double operator*(const point &a,const point &b)
{
    return a.x*b.x+a.y*b.y+a.z*b.z;
}
point operator^(const point &a,const 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);
}
double Volcume(const point &a,const point &b,const point &c,const point &d)
{
    return ((b-a)^(c-a))*(d-a);
}
set<pair<int,int> >myset;
vector<pair<int, pair<int,int> > >faces;
point data[maxn];
int n;
void wrap(int a,int b)
{
    if(myset.find(make_pair(a,b))==myset.end())
    {
        int c=-1;
        for(int i=0; i<n; i++)
            if(i!=a&&i!=b)
            {
                if(c==-1||Volcume(data[c],data[a],data[b],data[i])>0)
                    c=i;
            }
        if(c!=-1)
        {
            faces.push_back(make_pair(a,make_pair(b,c)));
            myset.insert(make_pair(a,b));
            myset.insert(make_pair(b,c));
            myset.insert(make_pair(c,a));
            wrap(c,b),wrap(a,c);
        }
    }
}
double sqr(double x)
{
    return x*x;
}
double dis(point a,point b)
{
    return sqrt(sqr(a.x-b.x)+sqr(a.y-b.y)+sqr(a.z-b.z));
}
double area(point a,point b,point c)
{
    double a1=dis(b,c),b1=dis(a,c),c1=dis(a,b),t=(a1+b1+c1)/2;
    return sqrt(t*(t-a1)*(t-b1)*(t-c1));
}
int main()
{
    while(~scanf("%d",&n))
    {
        for(int i=0; i<n; i++)scanf("%lf%lf%lf",&data[i].x,&data[i].y,&data[i].z);
        for(int i=1; i<n; i++)
            if(data[i].x<data[0].x) swap(data[i],data[0]);
        for(int i=2; i<n; i++)
            if((data[i].x-data[0].x)*(data[1].y-data[0].y)>(data[i].y-data[0].y)*(data[1].x-data[0].x))
                swap(data[1],data[i]);
        wrap(0,1);
        double ans=0;
        for(int i=0; i<(int)faces.size(); i++)
            ans+=area(data[faces[i].first],data[faces[i].second.first],data[faces[i].second.second]);
        printf("%.3f\n",ans);
    }
    return 0;
}

POJ 2974

#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<set>
#include<vector>
#include<map>
#include<cmath>
#define maxn 1000
using namespace std;
struct point
{
    double x,y,z;
    point() {}
    point(double _x,double _y,double _z):x(_x),y(_y),z(_z) {}
};
point operator-(const point &a,const point &b)
{
    return point(a.x-b.x,a.y-b.y,a.z-b.z);
}
double operator*(const point &a,const point &b)
{
    return a.x*b.x+a.y*b.y+a.z*b.z;
}
point operator^(const point &a,const 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);
}
double Volcume(const point &a,const point &b,const point &c,const point &d)
{
    return ((b-a)^(c-a))*(d-a);
}
set<pair<int,int> >myset;
vector<pair<int, pair<int,int> > >faces;
point data[maxn];
int n;
void wrap(int a,int b)
{
    if(myset.find(make_pair(a,b))==myset.end())
    {
        int c=-1;
        for(int i=0; i<n; i++)
            if(i!=a&&i!=b)
            {
                if(c==-1||Volcume(data[c],data[a],data[b],data[i])>0)
                    c=i;
            }
        if(c!=-1)
        {
            faces.push_back(make_pair(a,make_pair(b,c)));
            myset.insert(make_pair(a,b));
            myset.insert(make_pair(b,c));
            myset.insert(make_pair(c,a));
            wrap(c,b),wrap(a,c);
        }
    }
}
double sqr(double x)
{
    return x*x;
}
double dis(point a,point b)
{
    return sqrt(sqr(a.x-b.x)+sqr(a.y-b.y)+sqr(a.z-b.z));
}
double area(point a,point b,point c)
{
    double a1=dis(b,c),b1=dis(a,c),c1=dis(a,b),t=(a1+b1+c1)/2;
    return sqrt(t*(t-a1)*(t-b1)*(t-c1));
}
int main()
{
    while(~scanf("%d",&n),n)
    {
        myset.clear(),faces.clear();
        for(int i=0; i<n; i++)scanf("%lf%lf%lf",&data[i].x,&data[i].y,&data[i].z);
        for(int i=1; i<n; i++)
            if(data[i].x<data[0].x) swap(data[i],data[0]);
        for(int i=2; i<n; i++)
            if((data[i].x-data[0].x)*(data[1].y-data[0].y)>(data[i].y-data[0].y)*(data[1].x-data[0].x))
                swap(data[1],data[i]);
        wrap(0,1);
        double ans=0;
        for(int i=0; i<(int)faces.size(); i++)
            ans+=area(data[faces[i].first],data[faces[i].second.first],data[faces[i].second.second]);
        printf("%.0f\n",ans);
    }
    return 0;
}
时间: 2024-08-24 05:50:55

POJ 3528 &amp; POJ 2974 三维凸包的相关文章

三维凸包算法(英文名:Convex Hull)求教!

问题描述 三维凸包算法(英文名:Convex Hull)求教! 本人最近在做的一项研究需要用到三维凸包算法,主要是想用来计算物体表面凹陷处的体积,但从网上搜到的资源十分有限,不知哪位高人对这方面有所研究,还望能够指点一二,不胜涕零感激!!

HDU 3662 三维凸包表面多边形个数

题意:求三维凸包表面多边形个数. 我是来试模板的= = #include<stdio.h> #include<algorithm> #include<string.h> #include<math.h> #include<stdlib.h> using namespace std; const int MAXN=1050; const double eps=1e-8; struct Point { double x,y,z; Point() {}

输入问题-求三维凸包的程序,读不太懂,不知道应该输入什么

问题描述 求三维凸包的程序,读不太懂,不知道应该输入什么 源代码链接:http://www.cise.ufl.edu/class/cap5705fa11/openGL/delauney/dt2.c 先把Main函数和ReadVertices函数代码放上,求指点,输入到底该是什么呢? main( int argc, char *argv[] ) { if ( argc > 1 && argv[1][0] == '-' ) { if( argv[1][1] == 'd' ) { debu

POJ 3218 TOYS(计算几何)(二分)

TOYS:http://poj.org/problem?id=2318 大意:给你一个箱子,有n个挡板分隔成n+1部分,给你m个玩具的坐标,问每一部分有几个玩具. 思路:举对每个玩具,二分线段下标,判断玩具在线段左边还是右边,枚举后统计. 更多精彩内容:http://www.bianceng.cnhttp://www.bianceng.cn/Programming/sjjg/ #include <map> #include <stack> #include <queue>

poj 3522 Slim Span:枚举+最小生成树

链接: http://poj.org/problem?id=3522 题目: Slim Span Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 4962   Accepted: 2587 Description Given an undirected weighted graph G, you should find one of spanning trees specified as follows. The grap

UVa 755 / POJ 1002 487--3279 (排序)

755 - 487--3279 Time limit: 3.000 seconds http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=98&page=show_problem&problem=696 http://poj.org/problem?id=1002 Businesses like to have memorable telephone numbers. On

POJ 2385 Apple Catching (DP)

Description It is a little known fact that cows love apples. Farmer John has two apple trees (which are conveniently numbered 1 and 2) in his field, each full of apples. Bessie cannot reach the apples when they are on the tree, so she must wait for t

POJ 1833 排列 (STL)

排列 http://poj.org/problem?id=1833 Time Limit: 1000MS Memory Limit: 30000K Description 题目描述: 大家知道,给出正整数n,则1到n这n个数可以构成n!种排列,把这些排列按照从小到大的顺序(字典顺序)列出,如n=3时,列出1 2 3,1 3 2,2 1 3,2 3 1,3 1 2,3 2 1六个排列. 任务描述: 给出某个排列,求出这个排列的下k个排列,如果遇到最后一个排列,则下1排列为第1个排列,即排列1 2

算法题之poj 1961 Period(KMP, 最短循环节)

题目链接: POJ  : http://poj.org/problem?id=1961 HDU : http://acm.hdu.edu.cn/showproblem.php?pid=1358 ZOJ   : http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2177 题目大意: 给定一个长度为n的字符串s,求它的每个前缀的最短循环节.换句话说,对于每个i (2<=i<=n),求一个最大的整数K>1(如果K存在),使