POJ-2002 Squares Hash表+正方形顶点计算

该题的思路就是枚举所有的点,当然这么枚举要做到不能够重复和遗漏,所以我们约定值枚举对角线的两个点,最后将最终的结果除以2来计算。

由于每次通过枚举对角线的两个点,我们还要计算出另外两个顶点的坐标,所以这里用了一个很牛的公式,直接作加减法就能够出来了,判定下是否为整数。理论上我们马上要到点集中去寻找有没有这两个点,显然这种做法的效率很低,所以这里要用hash表,将顶点的信息的查询优化到接近O(1)。

这里把正方形计算另外两个顶点的公式记录如下(已知x1, x2, y1, y2, 求x3, y3, x4, y4):

  x1 + x2 = x3 + x4;

  y2 -  y1 = x4 -  x3;

  y1 + y2 = y3 + y4;

  x2 -  x1 = y3 -  y4;

代码如下:

#include <cstdlib>

#include <cstring>

#include <cstdio>

#include <algorithm>

#include <cmath>

#define MAXN 30001

#define MOD 30001

using namespace std;



int N, head[MAXN], idx;



struct Point

{

    int x, y;

}p[10005];



struct Node

{

    int x, y, next;

}e[10005];



void Hash(int x, int y)

{

    int key = abs(x * y) % MOD;

    ++idx;

    e[idx].x = x, e[idx].y = y;

    e[idx].next = head[key];

    head[key] = idx;

}



bool find(int x, int y)

{

    int key = abs(x * y) % MOD, ans = 0;

    for (int i = head[key]; i != -1; i = e[i].next) {

        if (e[i].x == x && e[i].y == y) {

            return true;

        }

    } 

    return false;

}



int main()

{

    int ans;

    while (scanf("%d", &N), N) {

        memset(head, 0xff, sizeof (head));

        idx = -1;

        ans = 0;

        for (int i = 0; i < N; ++i) {

            scanf("%d %d", &p[i].x, &p[i].y);    

            Hash(p[i].x, p[i].y);

        }

        double x1, y1, x2, y2;

        for (int i = 0; i < N; ++i) {

            for (int j = i+1; j < N; ++j) {

                x1 = ( (p[i].x + p[j].x) + (p[j].y - p[i].y) ) / 2.;

                x2 = ( (p[i].x + p[j].x) - (p[j].y - p[i].y) ) / 2.;

                y1 = ( (p[j].y + p[i].y) - (p[j].x - p[i].x) ) / 2.;

                y2 = ( (p[j].y + p[i].y) + (p[j].x - p[i].x) ) / 2.;

                if (x1 == floor(x1) && x2 == floor(x2) && y1 == floor(y1) && y2 == floor(y2)) {

                    if (find(x1, y1) && find(x2, y2)) {

                        ++ans;

                    } 

                }

            }

        }

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

    }

    return 0;

}

你可能感兴趣的:(hash表)