HDU5839-Special Tetrahedron(判断四点共面,叉乘求平面垂直向量)

63 篇文章 0 订阅
33 篇文章 0 订阅

Special Tetrahedron

                                                                           Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
                                                                                                        Total Submission(s): 750    Accepted Submission(s): 317


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
 

Author
UESTC
 

Source
 

Recommend
wange2014
 


题意:在三维空间中给出N个点,找有多少个满足条件的四面体。  四面体至少有四条边相等,若恰好四条边相等,那么剩下的两边不相邻。

解题思路:首先枚举该空间四边形中的一条对角线,再计算剩余的点跟这条对角线两端点的距离。若某点与这对角线两端点的距离相等, 则添加到一个集合中。枚举集合中的任意两点,与对角线两端点组成一个四边形,若集合中两点到对角线端点的距离相等且四点要不共面则满足。在上述判断过程中会出现重复计数:当四面体不为正四面体,由于每个四边形有两条对角线,所以在枚举对角形计数时,每个四边形都被计数了两次。若一个四面体是正四面体,那么这四个点被计数了6次。每当枚举到一个合法的空间四面体时,求一下剩下两条边是否跟其它边相等。

时间复杂度:上述过程看起来是 O(N^4)。而实际上,每次枚举对角线时,符合条件的点一定在这条对角线的中垂面上。所以不可能每次枚举对角线时,都有很多点在中垂面上。所以实际复杂度并不高。


#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <stack>
#include <cmath>
#include <map>
#include <bitset>
#include <set>
#include <vector>
#include <functional>

using namespace std;

#define LL long long
const int INF = 0x3f3f3f3f;

struct Point
{
	int x, y, z;
}p[210];

struct node
{
	int id, l;
}x[210];

int dis(Point p1, Point 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));
}

//叉积   
Point xmul(Point u, Point v)
{
	Point ans;
	ans.x = u.y*v.z - v.y*u.z;
	ans.y = u.z*v.x - u.x*v.z;
	ans.z = u.x*v.y - u.y*v.x;
	return ans;
}

//点积   
int 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 ans;
	ans.x = u.x - v.x;
	ans.y = u.y - v.y;
	ans.z = u.z - v.z;
	return ans;
}

//求平面的垂向量  
Point pvec(Point s1, Point s2, Point s3)
{
	return xmul(subt(s1, s2), subt(s2, s3));
}

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

int main()
{
	int t, n;
	int cas = 1;
	scanf("%d", &t);
	while (t--)
	{
		scanf("%d", &n);
		for (int i = 0; i<n; i++) scanf("%d%d%d", &p[i].x, &p[i].y, &p[i].z);
		int ans1 = 0; 
		int ans2 = 0; 
		for (int i = 0; i<n; i++)
		{
			for (int j = i + 1; j<n; j++)
			{
				int res = 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]))
					{
						x[res].id = k, x[res++].l = dis(p[i], p[k]);
					}
				}
				for (int k1 = 0; k1 <res; k1++)
				{
					for (int k2 = k1 + 1; k2 < res; k2++)
					{
						if (x[k1].l != x[k2].l) continue;
						if (check(p[i], p[j], p[x[k1].id], p[x[k2].id])) continue;
						if (dis(p[x[k1].id], p[x[k2].id]) == dis(p[i], p[j]) && dis(p[x[k1].id], p[x[k2].id]) == x[k1].l) ans2++;
						else ans1++;
					}
				}
			}
		}
		printf("Case #%d: %d\n", cas++, ans1 / 2 + ans2 / 6);
	}
	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值