2011 北京区域赛 Hou Yi's secret // hdu 4082

/*
2011 北京区域赛
Hou Yi's secret


题目:
    给出n个点,问任选三个点组成的三角形中最多有多少个相似

分析:
    能够组成三角形的话,点不能重复,不能三点共线,然后相似的判断可根据对应边
    的比值相等,由于边的长度涉及浮点运算,我们可以不开方直接用平方作比较就行

*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int X = 20;
const int maxn = 8000;

int n;
int map[X][X];
bool use[205][205];

struct node //n各点
{
    int x,y;
}p[X];

struct trangle  //三角形的三边长的平方
{
    int a,b,c;
}t[maxn];

int dist(int x1,int y1,int x2,int y2)
{
    return (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);
}

bool del(int i,int j,int k)
{
    int x1 = p[i].x-p[k].x;
    int y1 = p[i].y-p[k].y;

    int x2 = p[j].x-p[k].x;
    int y2 = p[j].y-p[k].y;

    if(x1*y2==x2*y1)
        return true;
    return false;
}

bool simillar(int i,int j)  //相似的判定
{
    int x = t[i].a;
    int y = t[i].b;
    int z = t[i].c;

    int a = t[j].a;
    int b = t[j].b;
    int c = t[j].c;

    if(x*b==y*a&&x*c==a*z&&y*c==b*z)
        return true;
    return false;
}

void solve()
{
    int temp[3];
    int cnt = 0;
    for(int i=1;i<=n;i++)
        for(int j=i+1;j<=n;j++)
            for(int k=j+1;k<=n;k++)
            {
                if(del(i,j,k))
                    continue;
                temp[0] = map[i][j];
                temp[1] = map[i][k];
                temp[2] = map[j][k];
                sort(temp,temp+3);  //对三边长度的平方排序,方便以后作比较

                t[++cnt].a = temp[0];
                t[cnt].b = temp[1];
                t[cnt].c = temp[2];
            }
    int ans = 0,cur;
    for(int i=1;i<=cnt;i++)
    {
        cur = 0;
        for(int j=i;j<=cnt;j++)
            if(simillar(i,j))
                cur++;
        ans = max(ans,cur);
    }
    cout<<ans<<endl;
}

int main()
{
    freopen("sum.in","r",stdin);
    freopen("sum.out","w",stdout);
    int m,x,y;
    while(cin>>m,m)
    {
        memset(use,false,sizeof(use));
        n = 0;
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d",&x,&y);
            x += 100;
            y += 100;
            if(use[x][y])   //去重
                continue;
            use[x][y] = true;
            p[++n].x = x;
            p[n].y = y;
        }
        for(int i=1;i<=n;i++)
            for(int j=i;j<=n;j++)   //预处理所有点与点距离的平方
                map[i][j] = map[j][i] = dist(p[i].x,p[i].y,p[j].x,p[j].y);
        solve();
    }

    return 0;
}
原文地址:https://www.cnblogs.com/yejinru/p/2548322.html