hdu 5839 三维几何 (暴力



链接:戳这里


Special Tetrahedron

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)

Problem Description
Given n points which are in three-dimensional space(without repetition).

Please find out how many distinct Special Tetrahedron among them. A tetrahedron is called Special Tetrahedron if it has two following characters.

1. At least four edges have the same length.

2. If it has exactly four edges of the same length, the other two edges are not adjacent.
 
Input
Intput contains multiple test cases. 

The first line is an integer T,1≤T≤20, the number of test cases.

Each case begins with an integer n(n≤200), indicating the number of the points.

The next n lines contains three integers xi,yi,zi, (−2000≤xi,yi,zi≤2000), representing the coordinates of the ith point.
 
Output
For each test case,output a line which contains"Case #x: y",x represents the xth test(starting from one),y is the number of Special Tetrahedron.
 
Sample Input
2
4
0 0 0
0 1 1
1 0 1
1 1 0
9
0 0 0
0 0 2
1 1 1
-1 -1 1
1 -1 1
-1 1 1
1 1 0
1 0 1
0 1 1
 
Sample Output
Case #1: 1
Case #2: 6


题意:

三维空间n个点,找出有多少个四面体满足

1:至少四条边相等,不相等的两条边是对边

2:六条边都相等


思路:

枚举两个点作为四面体的一条对角线,然后在统计剩余的点到该对角线端点的距离(现在的点集为p),那么在size-p*size-p枚举点集p中的点是否到两端点的距离相等,最后处理一下正四面体和共面 On^4
(比赛的时候想到一组数据会T这个思路,所以没写。。。就是200个点,198个空间等边三角形,这些三角形都只重一条边

代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<vector>
#include <ctime>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<iomanip>
#include<cmath>
#define mst(ss,b) memset((ss),(b),sizeof(ss))
#define maxn 0x3f3f3f3f
#define MAX 1000100
///#pragma comment(linker, "/STACK:102400000,102400000")
typedef long long ll;
typedef unsigned long long ull;
#define INF (1ll<<60)-1
using namespace std;
const long double  eps=1e-8;
#define zero(x) (((x)>0?(x):-(x))<eps)
struct point3{
    long double x,y,z;
    point3(long double x=0,long double y=0,long double z=0):x(x),y(y),z(z){}
};
typedef point3 vec3;
vec3 operator + (vec3 a,vec3 b){
    return vec3(a.x+b.x,a.y+b.y,a.z+b.z);
}
vec3 operator - (vec3 a,vec3 b){
    return vec3(a.x-b.x,a.y-b.y,a.z-b.z);
}
vec3 operator * (vec3 a,long double  p){
    return vec3(a.x*p,a.y*p,a.z*p);
}
vec3 operator / (vec3 a,long double  p){
    return vec3(a.x/p,a.y/p,a.z/p);
}
point3 operator * (point3 a,point3 b){
    return point3(a.y*b.z-a.z*b.y,a.z*b.x-a.x*b.z,a.x*b.y-a.y*b.x);
}
struct line3{
    point3 a,b;
};
struct plane3{
    point3 a,b,c;
};
point3 xmult(point3 u,point3 v){
    point3 ret;
    ret.x=u.y*v.z-v.y*u.z;
    ret.y=u.z*v.x-u.x*v.z;
    ret.z=u.x*v.y-u.y*v.x;
    return ret;
}
long double  dmult(point3 u,point3 v){
    return u.x*v.x+u.y*v.y+u.z*v.z;
}
point3 subt(point3 u,point3 v){
    point3 ret;
    ret.x=u.x-v.x;
    ret.y=u.y-v.y;
    ret.z=u.z-v.z;
    return ret;
}
/*****四面体体积*********/
long double  volume(point3 a, point3 b, point3 c, point3 d) {
    return fabs(dmult( (b - a) * (c - a) , (d - a) ) ) / 6.0;
}
/*****平面法向量*********/
point3 pvec(point3 s1,point3 s2,point3 s3){
    return xmult(subt(s1,s2),subt(s2,s3));
}
/*****两点距离***********/
long double  distance(point3 p1,point3 p2){
    return (p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y)+(p1.z-p2.z)*(p1.z-p2.z);
}
/*****向量长度***********/
long double  vlen(point3 p){
    return sqrt(p.x*p.x+p.y*p.y+p.z*p.z);
}
/*****点到平面距离***************/
long double  ptoplane(point3 p,point3 s1,point3 s2,point3 s3){
    return fabs(dmult(pvec(s1,s2,s3),subt(p,s1)))/vlen(pvec(s1 ,s2,s3));
}
/*****判四点共面*********/
int dots_onplane(point3 a,point3 b,point3 c,point3 d){
    return zero(dmult(pvec(a,b,c),subt(d,a)));
}
/*****判三点共线*********/
int dots_inline(point3 p1,point3 p2,point3 p3){
    return vlen(xmult(subt(p1,p2),subt(p2,p3)))<eps;
}
/*****点到平面的投影*****/
point3 shade_ptoplane(point3 p, point3 a, point3 b, point3 c) {
    point3 nor = (b - a) * (c - a);
    point3 nor0 = ( nor * dmult(nor, p - a) ) / vlen(nor) / vlen(nor);
    return (p - nor0);
}
/*****判两直线垂直*************************/
int perpendicular(point3 u1,point3 u2,point3 v1,point3 v2){
    return zero(dmult(subt(u1,u2),subt(v1,v2)));
}
long double  Dot(point3 a,point3 b){
    return a.x*b.x+a.y*b.y+a.z*b.z;
}
long double  Length(point3 a){
    return sqrt(Dot(a,a));
}
point3 Cross(point3 a,point3 b){
    return point3(a.y*b.z-a.z*b.y,a.z*b.x-a.x*b.z,a.x*b.y-a.y*b.x);
}
long double  area2(point3 a,point3 b,point3 c){
    return Length(Cross(b-a,c-a))*0.5;
}
bool operator == (point3 a,point3 b){
    if(fabs(a.x-b.x)==0 && fabs(a.y-b.y)==0 && fabs(a.z-b.z)==0)
        return true;
    return false;
}
int T,n;
point3 s[220];
struct node{
    long double d;
    int id;
    node(long double d=0,int id=0):d(d),id(id){}
}anw[40010];
int main(){
    scanf("%d",&T);
    for(int cas=1;cas<=T;cas++){
        scanf("%d",&n);
        for(int i=1;i<=n;i++) cin>>s[i].x>>s[i].y>>s[i].z;
        int ans=0,num=0;
        for(int i=1;i<=n;i++){
            for(int j=i+1;j<=n;j++){
                int cnt=0;
                for(int k=1;k<=n;k++){
                    long double d1=distance(s[i],s[k]);
                    long double d2=distance(s[j],s[k]);
                    if(fabs(d1-d2)<=eps){
                        anw[++cnt]=node(d1,k);
                    }
                }
                for(int k=1;k<=cnt;k++){
                    for(int l=k+1;l<=cnt;l++){
                        if(anw[k].d!=anw[l].d) continue;
                        if(dots_onplane(s[i],s[j],s[anw[k].id],s[anw[l].id])) continue;
                        long double d3=distance(s[anw[k].id],s[anw[l].id]);
                        long double d4=distance(s[i],s[j]);
                        if(fabs(d3-anw[k].d)<=eps && fabs(d3-d4)<=eps) num++;
                        else ans++;
                    }
                }
            }
        }
        printf("Case #%d: %d\n",cas,ans/2+num/6);
    }
    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值