HDU - 4082 Hou Yi's secret - 计算几何(水)

这道题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);
        }
    }
}




(观众:又丑又挫这代码也好意思贴上来!!!)







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值