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.
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.
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
题意:求四面体,有四条边相等,其他不等
思路:枚举两个点,剩余两点到这了量点的距离相等,注意正四面体。
#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);
}
}