HDU 4082 Hou Yi's secret

这是去年北京赛区的B题,给出n个点,用这些点构造三角形,然后找出相似三角形个数的最大值。

昨天看这题的时候以为很难,后面发现n的范围也就1818^3也不大,可以直接暴力做。构造三

角形的时候要注意两点:

1)这道题会有重点,需要判重。判重时可以将点平移,然后用一个200*200的数组做标记就行了。

2)判断三点共线,只需求出第一个与第三个点、第二个点与第三个点连线的斜率,斜率相等必然

共线。此外,处理的时候将a作为最小边、b作为中边、c作为最长边。方便判断相似。

 

/*Accepted    4082    0MS    416K    2343 B    G++    Yu*/

#include<stdio.h>

#include<string.h>

#include<stdlib.h>

#include<algorithm>

using namespace std;



const int MAXN = 20;

const int MAXM = 820;

int ans, n, d[MAXN][MAXN], m, ns;



int used[210][210];

struct point

{

    int x, y;

}p[MAXN];



struct triangle

{

    int a, b, c;

}t[MAXM];



int dist(point p1, point p2)//距离的平方

{

    int x, y;

    x = p1.x - p2.x;

    y = p1.y - p2.y;

    return x * x + y * y;

}



bool ponls(point p0, point p1, point p2)//共线,斜率相等

{

    int x1, x2, y1, y2;

    x1 = p0.x - p2.x;

    y1 = p0.y - p2.y;



    x2 = p1.x - p2.x;

    y2 = p1.y - p2.y;



    if(x1 * y2 == x2 * y1)

        return true;

    return false;

}



bool similar(triangle t1, triangle t2) //相似,对应边成比例

{

    int a1, a2, b1, b2, c1, c2;

    a1 = t1.a, b1 = t1.b, c1 = t1.c;

    a2 = t2.a, b2 = t2.b, c2 = t2.c;



    if(a1 * b2 == b1 * a2 && a1 * c2 == c1 * a2 && b1 * c2 == c1 * b2)

        return true;

    return false;

}



void ReadGraph()

{

    int i, j, k, s, v;

    n = 0;

    memset(used, 0, sizeof used);

    for(i = 1; i <= ns; i ++)

    {

        scanf("%d%d", &s, &v);

        s += 100, v += 100; //平移

        if(used[s][v]) continue;

        used[s][v] = 1;

        p[++ n].x = s;

        p[n]. y = v;

    }

    for(i = 1; i <= n; i ++)

        for(j = 1; j <= n; j ++)

            d[i][j] = d[j][i] = dist(p[i], p[j]);

}



void MakeTriangle()

{

    int i, j, k, temp[3];

    m = 0;

    for(i = 1; i <= n; i ++)

        for(j = i + 1; j <= n; j ++)

            for(k = j + 1; k <= n; k ++)

            {

                if(ponls(p[i], p[j], p[k]))

                    continue;

                temp[0] = d[i][j];

                temp[1] = d[j][k];

                temp[2] = d[i][k];

                sort(temp, temp + 3);

                t[++ m].a = temp[0];

                t[m].b = temp[1];

                t[m].c = temp[2];

            }

}



void cal()

{

    int cnt, i, j;

    ans = 0;

    for(i = 1; i <= m; i ++)

    {

        cnt = 1;

        for(j = i + 1; j <= m; j ++)

        {

            if( similar(t[i], t[j]))

                ++ cnt;

        }

        ans = max(ans, cnt);

    }

}



int main()

{

    while(scanf("%d", &ns), ns)

    {

        ReadGraph();

        MakeTriangle();

        cal();

        printf("%d\n", ans);

    }

    return 0;

}

 

 

 

 

你可能感兴趣的:(HDU)