您的位置:首页 > 其它

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

2012-06-13 18:22 218 查看
/*
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
.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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: