hdu5839Special 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,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

Author
UESTC

Source
2016中国大学生程序设计竞赛 - 网络选拔赛

给n个点。取多少个4个点可以组成一个特殊的4面体。特殊4面体至少4条边不等,如果恰好4条边相等,另外两条不相等的边不相邻。
//暴力n^4的枚举4个点作为对边,只要这除了这两个对边的边相等的话就满足题目要求,就算对边不相等,他也是的不相邻的。。所以直接暴力。注意判断4点共面的情况。以及去重。

#include<bits/stdc++.h>
using namespace std;

const double eps=1e-8;
struct point3{
    int x,y,z;
    point3(){};
    point3(int x,int y,int z):x(x),y(y),z(z){};
    bool operator < (const point3 &a)const{
        if(x!=a.x) return x<a.x;
        if(y!=a.y) return y<a.y;
        return z<a.z;
    }
    point3 operator + (const point3 &a)const{
        return point3(x+a.x,y+a.y,z+a.z);
    }
    bool operator == (const point3 &a) const{
        return (x==a.x&&y==a.y&&z==a.z);
    }

}p[205];
int dis2(const point3 &a,const point3 &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);
}
struct point4{
    point3 a[5];
    void ss(){
        sort(a,a+4);
    }
};
bool operator<(const point4 &x,const point4 &y){
    for(int i = 0;i < 4;++i){
        if(x.a[i] < y.a[i]){
            return true;
        }
        else if(y.a[i] < x.a[i]){
            return false;
        }
    }
    return false;
}
set<point4>Q;   //去重
set<point4>::iterator it;
int main(){
    int t;
    scanf("%d",&t);
    for(int cas=1;cas<=t;cas++){
        int n;
        scanf("%d",&n);
        for(int i=0;i<n;i++) scanf("%d %d %d",&p[i].x,&p[i].y,&p[i].z);

        int ans=0;
        Q.clear();
        for(int i=0;i<n;i++){
            for(int j=i+1 ;j<n;j++){
                for(int k=0;k<n;k++){
                    if(k==i||k==j) continue;
                    int d1=dis2(p[i],p[k]);
                    int d2=dis2(p[j],p[k]);
                    if(d1!=d2) continue;

                    for(int l=k+1;l<n;l++){

                        int d3=dis2(p[i],p[l]);
                        int d4=dis2(p[j],p[l]);
                        if(d3!=d4) continue;
                        if(d1!=d4) continue;

                        if(p[i]+p[j]==p[k]+p[l]) continue;  //4点共面

                        point4 dd;
                        dd.a[0]=p[i];
                        dd.a[1]=p[j];
                        dd.a[2]=p[k];
                        dd.a[3]=p[l];
                        dd.ss();
                        if(Q.find(dd)==Q.end()){
                           Q.insert(dd);
                            ans++;
                        }
                    }//l
                }//k
            }//j
        }//i
        printf("Case #%d: %d\n",cas,ans);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值