枚举对角线两点求出所有等腰三角形 然后继续枚举形成等腰三角形的第三点 四个嵌套循环但实际并没有这么多,个人认为这没有什么证明推论主要还是数学感觉的问题,多做题。。。 然后每个满足情况的四面体不是被统计两次就是被统计六次(正四面体)。。。去重就行了
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#define maxn 500
#define LL long long
using namespace std;
struct point
{
LL x,y,z;
}p[maxn];
int n;
LL 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);
}
point xMul(point a,point b)//求叉积
{
point c;
c.x = a.y * b.z - a.z * b.y;
c.y = a.z * b.x - a.x * b.z;
c.z = a.x * b.y - a.y * b.x;
return c;
}
LL dMul(point a,point b)//求点积
{
return a.x * b.x + a.y * b.y + a.z * b.z;
}
point subPoint(point a,point b)
{
point c;
c.x = a.x - b.x;
c.y = a.y - b.y;
c.z = a.z - b.z;
return c;
}
point nv(point a,point b,point c)//求法向量
{
return xMul(subPoint(a,b),subPoint(a,c));
}
bool ok(point a,point b,point c,point d)//判断四点共面
{
return dMul(nv(a,b,c),subPoint(a,d)) == 0;
}
LL st[maxn];
int main()
{
int t,i1 = 1;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(int i = 0;i < n; i++) scanf("%I64d %I64d %I64d",&p[i].x,&p[i].y,&p[i].z);
LL ans = 0,ans1 = 0,l;
for(int i=0;i<n;i++)
for(int j=i+1;j<n;j++)
{
l = 0;
for(int k=0;k<n;k++)
if(dis(p[k],p[i])==dis(p[k],p[j]))st[l++] = k;
for(int i1=0;i1<l;i1++)
for(int j1=i1+1;j1<l;j1++)
{
if(dis(p[st[i1]],p[i])!=dis(p[st[j1]],p[i])) continue;
if(ok(p[i],p[j],p[st[i1]],p[st[j1]])) continue;
ans++;
LL pre = dis(p[st[i1]],p[i]);
if(dis(p[st[i1]],p[st[j1]]) == pre && dis(p[i],p[j]) == pre)ans1++;
}
}
ans/=2;
ans1/=6;
printf("Case #%d: ",i1);
i1++;
printf("%I64d\n",ans-2*ans1);
}
return 0;
}