标签:
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
Case #1: 1
Case #2: 6
题目大意:
给了
解题思路:
首先我们将每两个点的距离算出来作为线段,将这些线段保留下来,然后两重循环枚举两条相等的
线段,然后再比较这两条直线的端点所到另一条直线的端点的距离是否和直线距离相等,每次枚举
的时候都得判断对边是不是想等,类似下图中,每次枚举红色的线,然后判断黄色或者黑色的,首
先那两条红色的线的四个点判断一下这四个点是不是在同一个平面上,然后再判断是不是特殊的四
面体,因为每次枚举对边,所以能够保证四条边相等,不想等的是对边。然后去重,用一个集合去
重一下就行了。
/**
2016 - 08 - 17 下午
Author: ITAK
Motto:
今日的我要超越昨日的我,明日的我要胜过今日的我,
以创作出更好的代码为目标,不断地超越自己。
**/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <queue>
#include <algorithm>
#include <set>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const int INF = 1e9+5;
const int MAXN = 2e2+5;
const int MOD = 1e9+7;
const double eps = 1e-7;
const double PI = acos(-1);
using namespace std;
LL Scan_LL()///输入外挂
{
LL res=0,ch,flag=0;
if((ch=getchar())==‘-‘)
flag=1;
else if(ch>=‘0‘&&ch<=‘9‘)
res=ch-‘0‘;
while((ch=getchar())>=‘0‘&&ch<=‘9‘)
res=res*10+ch-‘0‘;
return flag?-res:res;
}
int Scan_int()///输入外挂
{
int res=0,ch,flag=0;
if((ch=getchar())==‘-‘)
flag=1;
else if(ch>=‘0‘&&ch<=‘9‘)
res=ch-‘0‘;
while((ch=getchar())>=‘0‘&&ch<=‘9‘)
res=res*10+ch-‘0‘;
return flag?-res:res;
}
void Out(LL a)///输出外挂
{
if(a>9)
Out(a/10);
putchar(a%10+‘0‘);
}
struct Point
{
LL x, y, z;
} a[MAXN];
inline LL Get_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 Judge(Point a, Point b, Point c, Point d)///判断共面;
{
LL x1 = b.x-a.x, y1 = b.y-a.y, z1 = b.z-a.z;
LL x2 = c.x-a.x, y2 = c.y-a.y, z2 = c.z-a.z;
LL x3 = d.x-a.x, y3 = d.y-a.y, z3 = d.z-a.z;
LL tmp1 = x1*y2*z3+y1*z2*x3+z1*x2*y3;
LL tmp2 = z1*x3*y2+x2*y1*z3+x1*z2*y3;
if(tmp1 == tmp2)
return 1;
return 0;
}
struct Line
{
LL st, end, len;
} line[MAXN*MAXN];
inline bool cmp(Line a, Line b)
{
return a.len < b.len;
}
struct Check///去重
{
int ind[4];
bool operator < (const Check &x)const
{
if(ind[0] == x.ind[0])
{
if(ind[1] == x.ind[1])
{
if(ind[2] == x.ind[2])
return ind[3] < x.ind[3];
return ind[2] < x.ind[2];
}
return ind[1] < x.ind[1];
}
return ind[0] < x.ind[0];
}
};
set <Check> s;
int main()
{
int T, n;
T = Scan_int();
for(int cas=1; cas<=T; cas++)
{
s.clear();
n = Scan_int();
for(int i=0; i<n; i++)
{
a[i].x = Scan_LL();
a[i].y = Scan_LL();
a[i].z = Scan_LL();
}
int cnt = 0;
for(int i=0; i<n; i++)
{
for(int j=i+1; j<n; j++)
{
line[cnt].len = Get_Dis(a[i], a[j]);
line[cnt].st = i;
line[cnt++].end = j;
}
}
sort(line, line+cnt, cmp);
for(int i=0; i<cnt; i++)
{
Line p1 = line[i];
for(int j=i+1; ; j++)
{
Line p2 = line[j];
if(p1.len != p2.len)
break;
///cout<<p1.st<<" "<<p1.end<<" "<<p2.st<<" "<<p2.end<<endl;
if(Judge(a[p1.st], a[p1.end], a[p2.st], a[p2.end]))
continue;
if(p1.st!=p2.end && p1.end!=p2.st)
{
LL len1 = Get_Dis(a[p1.st], a[p2.st]);
LL len2 = Get_Dis(a[p1.st], a[p2.end]);
LL len3 = Get_Dis(a[p1.end], a[p2.end]);
LL len4 = Get_Dis(a[p1.end], a[p2.st]);
if( (len1==len3&&len1==p1.len) || (len2==len4&&len2==p2.len))
{
Check tp;
tp.ind[0] = p1.st;
tp.ind[1] = p1.end;
tp.ind[2] = p2.st;
tp.ind[3] = p2.end;
sort(tp.ind, tp.ind+4);
s.insert(tp);
}
}
}
}
LL ret = s.size();
printf("Case #%d: %I64d\n",cas,ret);
}
return 0;
}
HDU 5839 Special Tetrahedron(计算几何)
标签:
原文地址:http://blog.csdn.net/qingshui23/article/details/52229976