首页 > 代码库 > POJ2002_Squares (哈希表)

POJ2002_Squares (哈希表)

本文出自:blog.csdn.net/svitter

题意


  • A square is a 4-sided polygon whose sides have equal length and adjacent sides form 90-degree angles. It is also a polygon such that rotating about its centre by 90 degrees gives the same polygon. It is not the only polygon with the latter property, however, as a regular octagon also has this property.

    So we all know what a square looks like, but can we find all possible squares that can be formed from a set of stars in a night sky? To make the problem easier, we will assume that the night sky is a 2-dimensional plane, and each star is specified by its x and y coordinates.

  • 一共可以在给出的n个点中找出多少个正方形?

输入输出分析


  • The input consists of a number of test cases. Each test case starts with the integer n (1 <= n <= 1000) indicating the number of points to follow.

    Each of the next n lines specify the x and y coordinates (two integers) of each point.

    You may assume that the points are distinct and the magnitudes of the coordinates are less than 20000. The input is terminated when n = 0.

  • 有多组测试数据,每一个测试数据n开始,n <1000说明最多有1000个点。坐标系的横纵坐标不会超过20000, 以n=0结束

算法数据结构分析


本题目用哈希表+简单的分析做~

  • 给出4个点,如果四重循环N**4必然超时,那么枚举两个点来计算出对应的两个点,计算对应点是否存在

图片

  • 计算方法见getPoint()函数

  • 计算定应点是否存在的最快速度就是使用hash来查找。把(x+y)mod m,即取余法。最多有1000个点,所以哈希表1000个slot足够。

    保险起见,开1010,M取质数1009。

  • 使用拉链法解决冲突,开一个next数组,来保存下标i对应到hash表上,因为最多1000个节点,最糟糕的情况下需要999个卫星表, 所以next数组开·1010即可。

AC代码:

//author: svtter
//

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <vector>
#include <map>
#include <algorithm>
#include <queue>
#include <cmath>

#define INF 0xffffff
#define lln long long

#ifdef ONLINE_JUDGE
#define FOI(file) 0
#define FOW(file) 0
#else
#define FOI(file) freopen(file,"r",stdin);
#define FOW(file) freopen(file,"w",stdout);
#endif

using namespace std;

#define MAXN 1010 
#define MOD 1009
struct node
{
    int x, y;
    bool operator == (const node &a)const
    {
        return (x == a.x && y == a.y);
    }
    bool operator < (const node &a)const
    {
        if(x!=a.x)
            return x <a.x;
        return y < a.y;
    }
};
node point[MAXN];
int hash[MAXN+1], next[MAXN];



int n;

node c, d;
void getPoint(node &a, node &b) 
{
    c.x = b.x + (b.y - a.y);
    c.y = b.y - (b.x - a.x);
    d.x = a.x + (b.y - a.y);
    d.y = a.y - (b.x -a.x);
}

int getHash(node &a)
{
    return abs(a.x+ a.y) % MOD;
}

void insertHash(int i)
{
    //头插入,拉链法
    int key = getHash(point[i]);
    next[i] = hash[key];
    hash[key] = i;
}

bool search(node &t)
{
    int key = getHash(t);
    int i = hash[key];
    while(i != -1)
    {
        if(point[i] == t)
            return true;
        i = next[i];
    }
    return false;
}

int main()
{
    FOI("input");
    //FOW(output);

    int i, j;
    int ans;
    //write your programme here
    while(~scanf("%d", &n))
    {
        if(n == 0)
            break;
        memset(hash , -1 ,sizeof(hash));
        memset(next , -1, sizeof(next));
        for(i = 0; i < n; i++)
            scanf("%d%d", &point[i].x, &point[i].y);
        sort(point ,point+n);
        //puts("input over.");

        for(i = 0; i < n; i++)
            insertHash(i);
        //puts("build hash over.");

        ans = 0;
        for(i = 0; i < n; i++)
        {
            for(j = i+1; j < n; j++)
            {
                getPoint(point[i], point[j]);
                if(search(c) && search(d))
                    ans++;
            }
        }

        printf("%d\n", ans/2);
    }

    return 0;
}