hdu 5839 Special Tetrahedron (判断四面体)

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,1T20 , the number of test cases.

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

The next  n  lines contains three integers  xi,yi,zi (2000xi,yi,zi2000) , 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
 

题意:求四面体,有四条边相等,其他不等

思路:枚举两个点,剩余两点到这了量点的距离相等,注意正四面体。

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

#define LL long long

int n,m;
int T;


struct point
{
    double x,y,z;
    point() {}
    point(int x_,int y_,int z_):x(x_),y(y_),z(z_) {}

} p[250];

point xmul(point u, point v) {
    point 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;
}

LL dmul(point u, point v) {
    return u.x*v.x + u.y*v.y + u.z*v.z;
}

point subt(point u, point v) {
    point ret;
    ret.x = u.x - v.x;
    ret.y = u.y - v.y;
    ret.z = u.z - v.z;
    return ret;
}
/*求平面的垂向量*/
point pvec(point s1, point s2, point s3) {
    return xmul(subt(s1,s2),subt(s2,s3));
}

/*判断四点共面*/
bool is_ok(point a, point b, point c, point d) {
    return (dmul(pvec(a,b,c),subt(d,a))) == 0LL;
}

double dis(point a,point b)
{
    return (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y) + (a.z-b.z) *  (a.z-b.z) ;

}

bool is_plain(point a,point b,point c,point d)
{
    point s1,s2,s3;
    s1.x=b.x-a.x;s1.y=b.y-a.y;s1.z=b.z-a.z;
    s2.x=c.x-a.x;s2.y=c.y-a.y;s2.z=c.z-a.z;
    s3.x=d.x-a.x;s3.y=d.y-a.y;s3.z=d.z-a.z;
    double ans=s1.x*s2.y*s3.z+s1.y*s2.z*s3.x+s1.z*s2.x*s3.y-s1.z*s2.y*s3.x-s1.x*s2.z*s3.y-s1.y*s2.x*s3.z;
    if(ans==0)return true;
    return false;
}

int Q[250];


int main()
{
    int cas=0;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);

        for(int i=0; i<n; i++)
        {
            scanf("%lf%lf%lf",&p[i].x,&p[i].y,&p[i].z);
        }

        int ans1=0,ans2=0;

        for(int i=0; i<n; i++)
            for(int j=i+1; j<n; j++)
            {
                int cnt=0;
                for(int k=0; k<n; k++)
                {
                    if(k==i||k==j) continue;
                    if(dis(p[i],p[k]) == dis(p[j],p[k]))
                    {
                        Q[cnt++] = k;
                    }
                }
                if(cnt<=1) continue;

                for(int cc=0; cc<cnt; cc++)
                    for(int jj = cc+1; jj<cnt; jj++)
                    {
                         int pp = Q[cc],q=Q[jj];

                         if(dis(p[pp],p[i])!= dis(p[q],p[i])) continue;
                         if(is_plain(p[i],p[j],p[pp],p[q])) continue;

                         if(dis(p[i],p[j]) == dis(p[pp],p[q]) && dis(p[i],p[j] )== dis(p[pp],p[i]) ) ans2++;
                         else ans1++;
                    }
            }

       printf("Case #%d: %d\n",++cas,ans1/2+ans2/6);

    }

}







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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值