题意:
给出n个点,有两个人,每个人可以选3个点,问有多少种情况是可以找出两个三角形,是可以通过旋转使其全等。
思路:
所以首先要是三角形即三点不能共线,其次要全等,即三条边对应相等,最后判断是否对称,如果对称无论如何旋转都无法重合
所以利用叉积选好对应边,如果两个叉积互为相反数,则说明对称否则可以重合,这里注意一种特殊情况,等边三角形要提前判断,因为等边三角形不需要判断叉积只要全等一定可以通过旋转平移重合
直接暴力枚举六个不同的点即可
代码:
#include<cstdio> #include<algorithm> #include<cstring> #include<cstring> #include<iostream> #include<sstream> #include<cmath> #define LL long long #define INF 0x3f3f3f3f #define eps 1e-6 using namespace std; int n; int T; int ans; struct node { int x,y; node (){}; node(int x,int y):x(x),y(y){}; node operator - (node p) { return node(x-p.x,y-p.y); } int operator *(node p){ return x*p.y-y*p.x; } }E[15]; int vis[11][11][11][11][11][11]; double dis(node a,node b) { return sqrt((a.x-b.x)*(a.x-b.x)*1.0+(a.y-b.y)*(a.y-b.y)*1.0); } int check(int a,int b,int c,int d,int e,int f){ int a1[3] = {a,b,c}; int a2[3] = {d,e,f}; sort(a1,a1+3); sort(a2,a2+3); if(vis[a1[0]][a1[1]][a1[2]][a2[0]][a2[1]][a2[2]]==0){ vis[a1[0]][a1[1]][a1[2]][a2[0]][a2[1]][a2[2]]=1; return 1; } else return 0; } int dis2(node a,node b) { return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y); } int main() { scanf("%d",&T); int kase = 1; while(T--){ ans = 0; scanf("%d",&n); for(int i = 0;i<n;i++){ scanf("%d%d",&E[i].x,&E[i].y); } memset(vis,0,sizeof(vis)); for(int i = 0;i<n;i++){ for(int j = 0;j<n;j++){ if(i==j) continue; for(int k = 0;k<n;k++){ if(i==k||j==k) continue; for(int m = 0;m<n;m++){ if(fabs(dis(E[i],E[k])-dis(E[j],E[m]))>eps) continue; if(m==i||m==j||m==k) continue; for(int l = 0;l<n;l++) { if(l==i||l==j||l==k||l==m) continue; for(int o = 0;o<n;o++){ if(fabs(dis(E[i],E[l])-dis(E[j],E[o]))>eps||fabs(dis(E[k],E[l])-dis(E[m],E[o]))>eps) continue; if(o==i||o==j||o==k||o==m||o==l) continue; if((((E[i]-E[k])*(E[i]-E[l]))*((E[j]-E[m])*(E[j]-E[o])))<0) continue; double len1[3]; double len2[3]; len1[0] = dis(E[i],E[k]); len1[1] = dis(E[i],E[l]); len1[2] = dis(E[k],E[l]); len2[0] = dis(E[j],E[m]); len2[1] = dis(E[j],E[o]); len2[2] = dis(E[m],E[o]); sort(len1,len1+3); sort(len2,len2+3); if(fabs(len1[2]-len1[0]-len1[1])<=eps) continue; if(fabs(len2[2]-len2[0]-len2[1])<=eps) continue; // if(!check(i,k,l,j,m,o)) // continue; ans++; } } } } } } printf("Case %d: %d ",kase++,ans/6); } }