FZU 2270 Two Triangles (计算几何)

来源:互联网 发布:java生日祝福程序代码 编辑:程序博客网 时间:2024/06/05 19:46

注意:

  1. 注意判断三点共线
  2. 注意三角形的判定,对称的不计。
  3. 注意判别重合状态,防止计数计多了。
#include<cstdio>#include<cstring>#include<algorithm>#include <cmath>#define eps 1e-6typedef long long int lli;using namespace std;struct node{    int x,y;    node (){}    node (int xx,int yy){x=xx,y=yy;}    node operator - (node t){        return node(x-t.x,y-t.y);    }    int operator * (node t){        return x*t.y - t.x*y;    }}a[30];int dis(int i,int j){    return ((a[i].x-a[j].x)*(a[i].x-a[j].x) + (a[i].y-a[j].y)*(a[i].y-a[j].y) );}int t,n,ans;int v[12][12][12][12][12][12];//判重 imk为一个三角形 jlo为另一个bool ff(int ii,int jj,int kk,int ll,int mm,int oo,int flag){//flag为1代表需要修改值    int cnt[3] = {ii,mm,kk};int cnt2[3] = {jj,ll,oo};    sort(cnt,cnt+3);sort(cnt2,cnt2+3);    if(v[cnt[0]][cnt[1]][cnt[2]][cnt2[0]][cnt2[1]][cnt2[2]] == 0){        if(flag) v[cnt[0]][cnt[1]][cnt[2]][cnt2[0]][cnt2[1]][cnt2[2]] = 1;        return false;    }    else        return true;}int main(){    scanf("%d",&t);int ncase = 0;    while(t--){        ncase++;        scanf("%d",&n);ans = 0;        memset(v,0,sizeof(v));        for(int i = 1;i <= n;i++){            scanf("%d%d",&a[i].x,&a[i].y);        }        for(int i = 1;i <= n;i++){// 找到一个6个数字各不相同的            for(int j = 1;j <= n;j++){                if(i==j) continue;                for(int k = 1;k <= n;k++){                    if(i==k||j==k)continue;                    for(int l= 1;l <= n;l++){                        if(i==l||j==l||k==l) continue;                        if(dis(i,k) != dis(j,l)) continue;                        for(int m = 1;m <= n;m++){                            if(i==m||j==m||k==m||l==m)continue;                            for(int o=1;o <= n && !ff(i,j,k,l,m,o,0);o++){                                if(i==o||j==o||k==o||l==o||m==o)continue;                                if(dis(k,m) == dis(l,o) && dis(i,m)==dis(j,o)){                                    if( ((a[k]-a[i])*(a[m]-a[k])) * ((a[l]-a[j])*(a[o]-a[l])) >= 0  //判断对称 如果对称 那么不行                                        && ((a[m]-a[k])*(a[i]-a[m])) * ((a[o]-a[l])*(a[j]-a[o])) >= 0                                        && ((a[i]-a[m])*(a[k]-a[i])) * ((a[j]-a[o])*(a[l]-a[j])) >= 0                                        ){                                        int len[3] = {dis(i,k),dis(k,m),dis(m,i)};//判断三点共线                                        sort(len,len+3);                                        double l1=sqrt(len[0]);                                        double l2=sqrt(len[1]);                                        double l3=sqrt(len[2]);                                        if(l1+l2 <= l3+eps)                                            break;                                        ans++;                                        ff(i,j,k,l,m,o,1);                                    }                                }                            }                        }                    }                }            }        }        printf("Case %d: %d\n",ncase,ans);    }    return 0;}