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; }