参考博客:
https://blog.csdn.net/bigbigship/article/details/44516115
这题看到别人的题解真的坑点蛮多的,自己第一次遇到,比如考察重复点的问题,考虑是否能构成一个三角形,还有判断相似的时候把除法移项为乘法后还需要考察精度问题(虽然不知道为什么是1e-8,可能比较吉利吧。。),这是因为在计算三角形的边长时sqrt开方会有浮点误差。
还有,网上有说在判断相似的时候用角度判断的,也有说用边长判断的,个人感觉用边长判断误差可能小一点。三条边排个序再一一对应成比例就可以了。
也许我这种菜逼就应该记住枚举点的格式吧。。。
//Hou Yi's secret
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;
#define MAXN 20
#define eps 1e-8
struct Tri
{
double L[4];//三条边,便于排序
}T[MAXN*MAXN*MAXN];//三角形整体
int X[MAXN],Y[MAXN];
bool Judge(int i,int j,int k)
{
if((X[i]-X[j])*(Y[k]-Y[j])==(X[k]-X[j])*(Y[i]-Y[j]))//三点共线
return false;
else
return true;
}
double Line(int a,int b)//求三条边长
{
return sqrt((X[a]-X[b])*(X[a]-X[b])+(Y[a]-Y[b])*(Y[a]-Y[b]));
}
bool Similar(int a,int b)
{
if(fabs(T[a].L[1]*T[b].L[2]-T[b].L[1]*T[a].L[2])<=eps&&fabs(T[a].L[2]*T[b].L[3]-T[a].L[3]*T[b].L[2])<=eps&&fabs(T[a].L[1]*T[b].L[3]-T[a].L[3]*T[b].L[1])<=eps)
return true;
else
return false;
}
int main()
{
int i,j,k;
int N;
int cnt,ans,temp;
while(scanf("%d",&N)&&N)
{
memset(X,0,sizeof(X));
memset(Y,0,sizeof(Y));
for(i=1;i<=N;i++)
{
scanf("%d%d",&X[i],&Y[i]);
for(j=1;j<i;j++)//判断并排除重点
{
if(X[j]==X[i]&&Y[j]==Y[i])//前面已经排查了重点,所以全是不相同的点
{
i--;
N--;
break;
}
}
}
if(N<3)
{
printf("%d\n",0);
continue;
}
cnt=0;
for(i=1;i<=N;i++)//建立三角形,用枚举三个点
{
for(j=i+1;j<=N;j++)
{
for(k=j+1;k<=N;k++)
{
if(Judge(i,j,k))//先判断是否能够构成三角形,即是否共线
{
T[++cnt].L[1]=Line(i,j);//求三条边长
T[cnt].L[2]=Line(i,k);
T[cnt].L[3]=Line(j,k);
sort(T[cnt].L+1,T[cnt].L+1+3);//从小到大
}
}
}
}
ans=0;
temp=cnt;
for(i=1;i<=temp;i++)//判断是否相似
{
cnt=1;
for(j=i+1;j<=temp;j++)
if(Similar(i,j))
cnt++;
ans=max(ans,cnt);
}
printf("%d\n",ans);
}
return 0;
}