FZU 2270 Two Triangles (计算几何)

注意:

  1. 注意判断三点共线
  2. 注意三角形的判定,对称的不计。
  3. 注意判别重合状态,防止计数计多了。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include <cmath>
#define eps 1e-6
typedef 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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值