首页 > 代码库 > 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; }