2016中国大学生程序设计竞赛 - 网络选拔赛 1008 Special Tetrahedron hdu5839

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
 
网络赛的时候如果看下这题就好了。。
---------------------------------------------------------------------
这题的n只有200,所以我们考虑枚举这个四面体的对角线,然后统计其余各个点到对角线两个点的距离。如果相同则加入队列,记这个距离为dis
然后两两枚举加入队列的点,如果dis相同则可以构成题中所给的四面体
用混合积判断一下是否共面然后统计答案sum。
不过这样会重复统计,对于非正四面体,会重复统计一倍,对于正四面体会重复3次
记正四面体有sx个。
那么答案ans=(sum/2-sx/3)
#include<map>
#include<cmath>
#include<queue>
#include<vector>
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
struct point
{
	long long x,y,z;
	long long dis;
}p[201],px[201];
inline long long dis(point x,point y)
{
	return (x.x-y.x)*(x.x-y.x)+(x.y-y.y)*(x.y-y.y)+(x.z-y.z)*(x.z-y.z);
}
inline bool check(point x,point y,point z,point w)
{
	long long x1=y.x-x.x,y1=y.y-x.y,z1=y.z-x.z;
	long long x2=z.x-x.x,y2=z.y-x.y,z2=z.z-x.z;
	long long x3=w.x-x.x,y3=w.y-x.y,z3=w.z-x.z;
	long long x4=y1*z2-y2*z1,y4=z1*x2-z2*x1,z4=x1*y2-x2*y1;
	//(a1,a2,a3)x(b1,b2,b3)=(a2b3-a3b2,a3b1-a1b3,a1b2-a2b1)
	long long v=x4*x3+y4*y3+z4*z3;
	if(v==0)
		return false;
	return true;
}
int main()
{
	int T,kx=0;
	scanf("%d",&T);
	while(T>0)
	{
		T--;
		kx++;
		int n;
		scanf("%d",&n);
		int i,j,k,l;
		for(i=1;i<=n;i++)
			scanf("%I64d%I64d%I64d",&p[i].x,&p[i].y,&p[i].z);
		int sum=0,sx=0;
		for(i=1;i<=n;i++)
		{
			for(j=i+1;j<=n;j++)
			{
				int tot=0;
				for(k=1;k<=n;k++)
				{
					if(dis(p[i],p[k])==dis(p[j],p[k]))
					{
						tot++;
						px[tot]=p[k];
						px[tot].dis=dis(p[i],p[k]);
					}
				}
				for(k=1;k<=tot;k++)
				{
					for(l=k+1;l<=tot;l++)
					{
						if(px[k].dis!=px[l].dis)
							continue;
						if(!check(p[i],p[j],px[k],px[l]))
							continue;
						sum++;
						if(dis(p[i],p[j])==px[k].dis&&dis(px[k],px[l])==px[k].dis)
							sx++;
					}
				}
			}
		}
		printf("Case #%d: %d\n",kx,(sum/2-sx/3));
	}
	return 0;
}




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值