hdu4082 Hou Yi's secret--相似三角形个数

原题链接: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;
}




  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值