n^4暴力,但实际上复杂度达不到n^4【和出题人是否懒惰有关,233
暴力枚举两个点,然后再枚举离这两点距离相同的点。
再枚举四个点,找到这个四边形四边相同,但是不共面的四个点。
再判断这个是不是正四边形,如果是正四边形的话,你会重复计算6次
否则重复计算两次。
代码如下:
#include<stdio.h> #include<string.h> #include<stdlib.h> #include<limits.h> #include<queue> #include<math.h> #include<stack> #include<vector> #include<algorithm> using namespace std; #define maxn 205 struct node { int x; int y; int z; }a[maxn]; long long dis(node a,node b); int sq(int a); bool check(node a,node b,node c,node d); bool check(node a,node b,node c,node d) { node s1,s2,s3; s1.x=b.x-a.x;s1.y=b.y-a.y;s1.z=b.z-a.z; s2.x=c.x-a.x;s2.y=c.y-a.y;s2.z=c.z-a.z; s3.x=d.x-a.x;s3.y=d.y-a.y;s3.z=d.z-a.z; long long ans=s1.x*s2.y*s3.z+s1.y*s2.z*s3.x+s1.z*s2.x*s3.y-s1.z*s2.y*s3.x-s1.x*s2.z*s3.y-s1.y*s2.x*s3.z; if(ans==0)return 1;//如果三个方向向量组成的行列式为0,则四点共面 return 0; } int sq(int a) { return a*a; } long long dis(node a,node b) { return sq(a.x-b.x)+sq(a.y-b.y)+sq(a.z-b.z); } int s[maxn]; int main() { int T,n,m,i,j,k,h,ans,cases=0; long long ans1,ans2; scanf("%d",&T); while(T--) { memset(s,0,sizeof(s)); memset(a,0,sizeof(a)); ans1=0;ans2=0; scanf("%d",&n); for(i=1;i<=n;i++) scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z); for(i=1;i<=n;i++) { for(j=1+i;j<=n;j++) { int cnt=0; for(k=1;k<=n;k++) { if(k==i || k==j) continue; if(dis(a[i],a[k])==dis(a[j],a[k])) s[cnt++]=k; } if(cnt<=1) continue; else for(h=0;h<cnt;h++) { for(int h1=h+1;h1<cnt;h1++) { int id1=s[h],id2=s[h1]; if(dis(a[id1],a[i])!=dis(a[id2],a[i]))//相邻的两条边要相等 continue; if(check(a[i],a[j],a[id1],a[id2]))//判断四点是否共面 continue; if(dis(a[id1],a[id2])==dis(a[i],a[j]) && dis(a[id1],a[i])==dis(a[i],a[j])) ans1++; else ans2++; } } } } printf("Case #%d: %d\n",++cases,ans1/6+ans2/2); } }