POJ2002Squares(哈希)
http://poj.org/problem?id=2002
Description
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.
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.
Input
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.
Output
For each test case, print on a line the number of squares one can form from the given stars.
Sample Input
4 1 0 0 1 1 1 0 0 9 0 0 1 0 2 0 0 2 1 2 2 2 0 1 1 1 2 1 4 -2 5 3 7 0 0 5 2 0
Sample Output
1 6 1
题目大意就是给一些点的坐标,问最多可以构成多少个正方形。
直接四个点四个点地枚举肯定超时的,不可取。
普遍的做法是:先枚举两个点,通过数学公式得到另外2个点,使得这四个点能够成正方形。然后检查散点集中是否存在计算出来的那两个点,若存在,说明有一个正方形。
但这种做法会使同一个正方形按照不同的顺序被枚举了四次,因此最后的结果要除以4.
已知: (x1,y1) (x2,y2)
则: x3=x1+(y1-y2) y3= y1-(x1-x2)
x4=x2+(y1-y2) y4= y2-(x1-x2)
或
x3=x1-(y1-y2) y3= y1+(x1-x2)
x4=x2-(y1-y2) y4= y2+(x1-x2)
据说是利用全等三角形可以求得上面的公式
有兴趣的同学可以证明下。。。
这样就好做了,用哈希标记每一个点这样就是O(n^2)的算法了,n的范围是1000这肯定不会超时
具体建议参考ζёСяêτ - 小優YoU的博客http://blog.csdn.net/lyy289065406/article/details/6647405,说的相当清楚
下面附代码
1 #include <iostream> 2 #include <cstdio> 3 #include<cstring> 4 using namespace std; 5 6 const int prime = 100007; 7 int hash[prime+5]; 8 int next[prime+5]; 9 10 struct node 11 { 12 int x,y; 13 }nod[1005]; 14 15 void insert(int x,int y,int index)//加入哈希链表中 16 { 17 int h = (x*x+y*y) % prime;//哈希函数就是平方和取余 18 int u = hash[h]; 19 while(u) 20 { 21 u=next[u]; 22 } 23 next[index]=hash[h]; 24 hash[h]=index; 25 } 26 27 bool find(int x,int y) 28 { 29 int h = (x*x+y*y) % prime; 30 int u = hash[h]; 31 while(u) 32 { 33 if(nod[u].x==x && nod[u].y==y)return true; 34 u=next[u]; 35 } 36 return false; 37 } 38 39 int main() 40 { 41 int n; 42 while(~scanf("%d",&n)&&n) 43 { 44 memset(hash,0,sizeof(hash)); 45 memset(next,0,sizeof(next)); 46 47 int i,j; 48 for(i=1;i<=n;i++) 49 { 50 scanf("%d%d",&nod[i].x,&nod[i].y); 51 insert(nod[i].x,nod[i].y,i); 52 } 53 54 int x1,y1,x2,y2,count=0; 55 for(i=1;i<n;i++) 56 { 57 for(j=i+1;j<=n;j++) 58 { 59 x1=nod[i].x+(nod[i].y-nod[j].y); 60 y1=nod[i].y-(nod[i].x-nod[j].x); 61 x2=nod[j].x+(nod[i].y-nod[j].y); 62 y2=nod[j].y-(nod[i].x-nod[j].x); 63 if(find(x1,y1)&&find(x2,y2))count++; 64 65 x1=nod[i].x-(nod[i].y-nod[j].y); 66 y1=nod[i].y+(nod[i].x-nod[j].x); 67 x2=nod[j].x-(nod[i].y-nod[j].y); 68 y2=nod[j].y+(nod[i].x-nod[j].x); 69 if(find(x1,y1) && find(x2,y2))count++; 70 } 71 } 72 printf("%d\n",count/4); 73 } 74 return 0; 75 }