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. 

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 }

 

posted @ 2013-05-16 11:31  再见~雨泉  阅读(1100)  评论(0编辑  收藏  举报