#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <queue> #include <map> #include <vector> #define eps 1e-5 using namespace std; typedef long long ll; ll neq,eq,ans; int n; struct node { double x,y,z; }p[300]; bool cmp(node a,node b) { if(fabs(a.x-b.x)<=eps) { if(fabs(a.y-b.y)<=eps) return a.z<b.z; return a.y<b.y; } return a.x<b.x; } void work(node a,node b){ int getin[300],cnt=0; double dis1=(a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)+(a.z-b.z)*(a.z-b.z); double dis2; node mid,mid2; mid.x=(a.x+b.x)/2, mid.y=(a.y+b.y)/2, mid.z=(a.z+b.z)/2; double k1,k2,k3,d; k1=a.x-b.x,k2=a.y-b.y,k3=a.z-b.z; d=k1*mid.x+k2*mid.y+k3*mid.z; for(int i=0;i<n;i++) if(fabs(k1*p[i].x+k2*p[i].y+k3*p[i].z-d)<=eps) getin[cnt++]=i; if(cnt<1)return ; double m1,m2,m3,l1,l2,l3; for(int i=0;i<cnt;i++) { double tx=p[getin[i]].x,ty=p[getin[i]].y,tz=p[getin[i]].z; for(int j=i+1;j<cnt;j++) { double t2x=p[getin[j]].x,t2y=p[getin[j]].y,t2z=p[getin[j]].z; mid2.x=(tx+t2x)/2; mid2.y=(ty+t2y)/2; mid2.z=(tz+t2z)/2; m1=mid2.x-mid.x; m2=mid2.y-mid.y; m3=mid2.z-mid.z; if(fabs(m1)<=eps && fabs(m2)<=eps && fabs(m3)<=eps)continue; double dis3 = (tx-a.x)*(tx-a.x)+(ty-a.y)*(ty-a.y)+(tz-a.z)*(tz-a.z); l1=tx-t2x; l2=ty-t2y; l3=tz-t2z; if(fabs( m1*l1 + m2*l2 + m3*l3)<=eps) { dis2 = l1*l1 + l2*l2 + l3*l3; if(fabs((dis1-dis2))<=eps && fabs(dis3-dis1)<=eps)eq++; else neq++; } } } } int main() { int cas=0,T; scanf("%d",&T); while(T--) { ans=0,eq=0,neq=0; scanf("%d",&n); for(int i=0;i<n;i++) scanf("%lf%lf%lf",&p[i].x,&p[i].y,&p[i].z); sort(p,p+n,cmp); int nn=1; for(int i=1;i<n;i++) { if((fabs(p[i].x-p[i-1].x)<=eps)&&(fabs(p[i].y-p[i-1].y)<=eps)&&(fabs(p[i].z-p[i-1].z)<=eps)) continue; else { p[nn].x=p[i].x; p[nn].y=p[i].y; p[nn].z=p[i].z; nn++; } } n=nn; if(n<4) { printf("Case #%d: 0\n",++cas); continue; } for(int i=0;i<n;i++) for(int j=i+1;j<n;j++) work(p[i],p[j]); ans=eq/6+neq/2; printf("Case #%d: %I64d\n",++cas,ans); } return 0; }
|