这道题wa了好几天,各种卡,
先说说题意吧
题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=4082
题意:
给你n(n <= 18)个点,任意三点连线,找出最多的相似三角形。
参考博客:http://blog.youkuaiyun.com/bigbigship/article/details/44516115
思路:
我啥也不会,只会暴力。
枚举出所有的三角形(注意:存储三角形的时候要按照角度从大到小存起来),然后遍历一遍,如果相似,就加一。这里对我来说坑点(学到的东西):
1.涉及开根号的就不会精准,后面比较一定差值<= 1e-8。
2.去掉重复的点(三角形)
3.如果n<3,此时等待输入再输出0,和输入2后直接输出0都是可以的
3.三角形的判定我起初用的三个角对应相等,哇了无数发,最后看了题解,用对应边成比例的这一判定就A掉了,至于对应角度相等的那个判定,是由于写的太丑有错误没发现还是真的不应该用这个判定(精度问题),我已经没力气再去检验了,反正对拍时50组数据,用角度的判定编译时超慢。所以以后判断三角形相似就用对应边成比例吧。也不会去cosA来比较了。很方便~
上代码:
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
const int N = 20;
int n;
struct Node
{
int x;
int y;
} a[N];
struct Triangle
{
Node z;
Node zz;
Node zzz;
double ds1;
double ds2;
double ds3;
} t[N * N * N];
bool compare(Node a, Node b)
{
return a.x < b.x;
}
int b[205][205];
const double eps = 1e-8;
bool xiangsi(Triangle t1, Triangle t2)
{
if(fabs(t1.ds1 * t2.ds2 - t1.ds2 * t2.ds1) < eps &&
fabs(t1.ds2 * t2.ds3 - t1.ds3 * t2.ds2) < eps &&
fabs(t1.ds1 * t2.ds3 - t1.ds3 * t2.ds1) <eps)
return true;
else
return false;
}
double dis(Node a, Node b)
{
double dd = pow(a.x - b.x, 2) + pow(a.y - b.y, 2);
return dd;
}
int main()
{
// freopen("data.txt", "r", stdin);
// freopen("houyiWA.txt", "w", stdout);
// while(scanf("%d", &n)&& n)
while(scanf("%d", &n) == 1 && n)
{
int p = 0;
if(n < 3)
{
// puts("0");
printf("0\n");
// continue;
}
else if(n >= 3)
{
int qn = 0;
memset(a, 0, sizeof(a));
memset(b, 0, sizeof(b));
memset(t, 0, sizeof(t));
for(int i = 0; i < n; i ++)
{
scanf("%d%d", &a[i].x, &a[i].y);
if(b[a[i].x + 105][a[i].y + 105] == 0)
b[a[i].x + 105][a[i].y + 105] = 1;
else
{
i --;
qn ++;
n --;
}
}
sort(a, a + n, compare);
memset(t, 0, sizeof(t));
for(int i = 0; i < n ; i ++)
{
for(int j = i + 1; j < n ; j ++)
{
for(int k = j + 1; k < n ; k ++)
{
(t[p].z).x = a[i].x;
(t[p].z).y = a[i].y;
(t[p].zz).x = a[j].x;
(t[p].zz).y = a[j].y;
(t[p].zzz).x = a[k].x;
(t[p].zzz).y = a[k].y;
if( fabs(((a[i].y - a[j].y) * (a[j].x - a[k].x)) - ((a[i].x - a[j].x) * (a[j].y - a[k].y)) )< eps)
continue;
t[p].ds1 = sqrt(pow(a[k].x - a[j].x, 2) + pow(a[k].y - a[j].y, 2));
t[p].ds2 = sqrt(pow(a[k].x - a[i].x, 2) + pow(a[k].y - a[i].y, 2));
t[p].ds3 = sqrt(pow(a[i].x - a[j].x, 2) + pow(a[i].y - a[j].y, 2)) ;
Node temp;
double qq;
if(t[p].ds1 > t[p].ds2)
{
temp = t[p].zz;
t[p].zz = t[p].z;
t[p].z = temp;
qq = t[p].ds1;
t[p].ds1 = t[p].ds2;
t[p].ds2 = qq;
}
if(t[p].ds1 > t[p].ds3)
{
temp = t[p].z;
t[p].z = t[p].zzz;
t[p].zzz = temp;
qq = t[p].ds1;
t[p].ds1 = t[p].ds3;
t[p].ds3 = qq;
}
if(t[p].ds2 > t[p].ds3)
{
temp = t[p].zz;
t[p].zz = t[p].zzz;
t[p].zzz = temp;
qq = t[p].ds2;
t[p].ds2 = t[p].ds3;
t[p].ds3 = qq;
}
p ++;
}
}
}
int ans = -1;
for(int i = 0; i < p; i ++)
{
int con = 0;
for(int j = 0; j < p; j ++)
{
if(j == i)
continue;
if(xiangsi(t[i], t[j]))
con ++;
}
if(ans < con)
ans = con;
}
printf("%d\n", ans + 1);
}
}
}
(观众:又丑又挫这代码也好意思贴上来!!!)