Two Triangles FZU

来源:互联网 发布:数据产品经理 步骤 编辑:程序博客网 时间:2024/06/06 02:20

Fat brother and Maze are playing a kind of special (hentai) game with some points in a two-dimensional plane. First Fat Brother would choose three different points and then Maze would choose other three different points. If both of the player’s points form a triangle, they would feel happy. Also, if these two triangles are exactly the same, they would feel even happier. The two triangles are considered the same if one can be changed from another by translation and rotation.

Now given N points in a plane, Fat Brother would like to know how many different sets of points they can choose in order to make them even happier.

Input

The first line of the data is an integer T (1 <= T <= 100), which is the number of the text cases.

Then T cases follow, each case contains an integer N (6 <= N <= 10) indicated the number of the points in the two-dimensional plane. The N lines follow, each line contains two integers x and y (0 <= x, y <= 10) shows this point’s coordinate. All the points have different coordinate in this plane.

Output

For each case, output the case number first, and then output the number of the different sets of points they can choose in order to make them even happier.

Sample Input
360 02 02 18 810 810 960 02 02 18 810 810 760 01 02 00 11 12 1
Sample Output
Case 1: 2Case 2: 0Case 3: 6
Hint

In the first case, Fat Brother can choose a set which contains first three points and Maze can choose a set which contains last three points, this makes a suitable answer. Also, Fat Brother and Maze can change the set they choose and still make a solid result.

题目大意:

给出n个点,有两个人,每个人可以选3个点,问有多少种情况是可以找出两个三角形,是可以通过旋转使其全等。

题目思路:

先通过暴力选出6个点,这里用6个for或者dfs都行,不过用dfs的话要知道选点的先后顺序。接下来就是判断全等了,我们知道,三条边相等的时全等三角形,但是这里用这个条件是不够的,题目是说通过旋转使其相等,不能是翻转,如果我们通过旋转使其成为一样的,是很麻烦的,我们可以反着想,找到不行的情况,在这里明显当两个三角形全等时,兑成的情况是不行的,所以我们只用判断对称的情况就行了,另外注意重复的情况,可以直接除6,或者用数组记录,怎么排除对称的情况呢,当我们找到全等时,我们利用叉积的性质来判断,只要判断认为相等的两条边的相对顺序是否相等就可以了,也就是是否都是顺时针,或者逆时针,表现在叉积的正负上。

ac代码:

#include<cstdio>#include<algorithm>#include<cstring>#include<cstring>#include<iostream>#include<sstream>#include<cmath>#define LL long long#define INF 0x3f3f3f3f#define eps 1e-6using 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\n",kase++,ans/6);   }}