hdu-5839 Special Tetrahedron(计算几何)
题目链接:
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.
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
题意:
问最少有四条边相同的四面体有多少个?
思路:
枚举一条边的两点,在枚举另外两点,在枚举第3个点的时候要判断是否是等腰三角形和三点是否共线,在枚举第4个点的时候要判断与前边两点是否是等腰三角形和是否共线(共线可以留在判断是否共面一块判断),还要判断这两个等腰三角形腰长是否相等;最后来到至少有4条边相等的四面体,如果它是正四面体就被重复算了6次,否则被重复算了两次;所有答案就出来了;
AC代码:
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> //#include <bits/stdc++.h> #include <stack> #include <map> using namespace std; #define For(i,j,n) for(int i=j;i<=n;i++) #define mst(ss,b) memset(ss,b,sizeof(ss)); typedef long long LL; template<class T> void read(T&num) { char CH; bool F=false; for(CH=getchar();CH<'0'||CH>'9';F= CH=='-',CH=getchar()); for(num=0;CH>='0'&&CH<='9';num=num*10+CH-'0',CH=getchar()); F && (num=-num); } int stk[70], tp; template<class T> inline void print(T p) { if(!p) { puts("0"); return; } while(p) stk[++ tp] = p%10, p/=10; while(tp) putchar(stk[tp--] + '0'); putchar('\n'); } const LL mod=1e9+7; const double PI=acos(-1.0); const int inf=1e9; const int N=1e5+10; const int maxn=210; const double eps=1e-12; int n; struct PO { int x,y,z; }po[maxn]; int check1(PO a,PO b,PO c)//判断共线; { PO temp1,temp2; temp1.x=a.x-b.x;temp1.y=a.y-b.y;temp1.z=a.z-b.z; temp2.x=c.x-b.x;temp2.y=c.y-b.y;temp2.z=c.z-b.z; if(temp1.x*temp2.y==temp1.y*temp2.x&&temp1.x*temp2.z==temp1.z*temp2.x&&temp1.y*temp2.z==temp1.z*temp2.y)return 1; return 0; } int check2(PO a,PO b,PO c,PO d)//判断共面; { int x1=b.x-a.x,y1=b.y-a.y,z1=b.z-a.z; int x2=c.x-a.x,y2=c.y-a.y,z2=c.z-a.z; int x3=d.x-a.x,y3=d.y-a.y,z3=d.z-a.z; LL t1=(LL)x1*y2*z3+y1*z2*x3+z1*x2*y3; LL t2=(LL)z1*x3*y2+x2*y1*z3+x1*z2*y3; if(t1==t2)return 1; return 0; } int dis(PO a,PO 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); } int solve() { int sum1=0,sum2=0; for(int i=1;i<=n;i++) { for(int j=i+1;j<=n;j++) { for(int k=1;k<=n;k++) { if(k==i||k==j)continue; int dist=dis(po[k],po[i]); if(dist!=dis(po[k],po[j]))continue; if(check1(po[i],po[j],po[k]))continue; for(int u=k+1;u<=n;u++) { if(u==i||u==j)continue; if(dis(po[u],po[i])!=dis(po[u],po[j]))continue; if(dis(po[u],po[i])!=dist)continue; //if(i==1&&j==2&&k==3)cout<<check2(po[k],po[u],po[i],po[j])<<u<<"&%&^^*(\n"; if(check2(po[u],po[k],po[i],po[j]))continue; if(dis(po[u],po[k])==dist&&dis(po[i],po[j])==dist)sum2++; else sum1++; } } } } return sum1/2+sum2/6; } int main() { int t,Case=0; read(t); while(t--) { read(n); For(i,1,n) { read(po[i].x);read(po[i].y);read(po[i].z); } printf("Case #%d: %d\n",++Case,solve()); } return 0; }