原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=4082
一:分析
有两个注意点:
1.重点
2.三点一线不能是三角形
最后题目要求是求出相似三角形的个数,就是假如现在只能凑出5个三角形,分别命名为t1,t2,,,t5。其中t1与t2相似,剩下三个互相相似,那么答案是输出3,而不是2+3=5。
二:AC代码
#define _CRT_SECURE_NO_DEPRECATE
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
struct Point
{
double x,y;
};
struct Triangle
{
double len[3];
};
Point point[20];
Triangle tri[20 * 20 * 20];
int isLine(Point p1, Point p2, Point p3)
{
return (p2.x - p1.x)*(p3.y - p1.y) - (p3.x - p1.x)*(p2.y - p1.y) == 0;
}
double dis(Point p1, Point p2)
{
return sqrt((p1.x - p2.x)*(p1.x - p2.x) + (p1.y - p2.y)*(p1.y - p2.y));
}
bool isSimilar(Triangle t1, Triangle t2)
{
if ((fabs(t1.len[0] * t2.len[1] - t1.len[1] * t2.len[0]) < 1e-8)&&
(fabs(t1.len[0] * t2.len[2] - t1.len[2] * t2.len[0]) < 1e-8)&&
(fabs(t1.len[1] * t2.len[2] - t1.len[2] * t2.len[1]) < 1e-8))
return true;
return false;
}
int main()
{
int n;//排除重复点,实际有多少点
while (~scanf("%d", &n) && n)
{
for (int i = 0; i < n; i++)
{
scanf("%lf%lf", &point[i].x, &point[i].y);
for (int j = 0; j < i; j++)
{
if (point[j].x == point[i].x&&point[j].y == point[i].y)
{
i--;
n--;
break;
}
}
}
if (n < 3)
{
printf("0\n");
continue;
}
//这里是不能的,因为3点可能一线,那么答案是0,而不是1
/*if (n == 3)
{
printf("1\n");
continue;
}*/
int cnt = 0;//有多少个三角形
for (int i = 0; i < n; i++)
{
for (int j = i + 1; j < n; j++)
{
for (int k = j + 1; k < n; k++)
{
if (!isLine(point[i], point[j], point[k]))
{
tri[cnt].len[0] = dis(point[i], point[j]);
tri[cnt].len[1] = dis(point[i], point[k]);
tri[cnt].len[2] = dis(point[j], point[k]);
sort(tri[cnt].len, tri[cnt].len + 3);
cnt++;
}
}
}
}
int ans = 0;
for (int i = 0; i < cnt; i++)
{
int t = 1;
for (int j = i + 1; j < cnt; j++)
if (isSimilar(tri[i], tri[j]))
t++;
ans = max(ans, t);
}
printf("%d\n", ans);
}
return 0;
}