Squares(哈希)
Time Limit: 3500MS | Memory Limit: 65536K | |
Total Submissions: 14328 | Accepted: 5393 |
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
题意:给出n个点的坐标,计算这些点可以构成多少个正方形,不同顺序的相同四个点被视为同一个正方形。
思路:这里n最大是1000,显然一个点一个点的枚举不行。参考了别人的结题报告,据说有这样的定理:
已知(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);
因此可以先枚举两个点,根据这两个点(点1 ,点2)的坐标可以得到另外两个点(点3, 点4),若在哈希表中能找得到这两个(点3, 点4),说明能构成一个正方形,
注意每个点被枚举了四次,最后要除以4;
再者就是找哈希函数,这里用的平方取余法,每输入一个点,就将这个点插入哈希表中;
这个题也受了 poj 3274的启发;
1 #include<stdio.h> 2 #include<string.h> 3 4 const int prime = 99991; 5 struct node 6 { 7 int x,y; 8 }pos[1010]; 9 10 struct HashTable 11 { 12 int x; 13 int y; 14 struct HashTable* next; 15 }*Hash[prime];//Hash[]是指针数组,存放地址; 16 int n; 17 18 //插入哈希表 19 void hash_insert(int x, int y) 20 { 21 int key = (x*x + y*y)%prime;//平方求余法; 22 if(!Hash[key]) 23 { 24 Hash[key] = new struct HashTable; 25 Hash[key]->x = x; 26 Hash[key]->y = y; 27 Hash[key]->next = NULL; 28 } 29 else 30 { 31 struct HashTable *tmp = Hash[key]; 32 while(tmp->next) 33 tmp = tmp->next;//开放寻址,直到next为空 34 //插入新结点 35 tmp->next = new struct HashTable; 36 tmp->next->x = x; 37 tmp->next->y = y; 38 tmp->next->next = NULL; 39 } 40 } 41 bool find(int x, int y) 42 { 43 int key = (x*x+y*y)%prime; 44 if(!Hash[key]) 45 return false;//key 对应的地址不存在, 46 else 47 { 48 struct HashTable *tmp = Hash[key]; 49 while(tmp) 50 { 51 if(tmp->x == x && tmp->y == y) 52 return true; 53 tmp = tmp->next; 54 } 55 return false; 56 } 57 } 58 int main() 59 { 60 while(scanf("%d",&n)!= EOF) 61 { 62 int i,j; 63 if(n == 0) break; 64 memset(Hash,0,sizeof(Hash)); 65 for(i = 0; i < n; i++) 66 { 67 scanf("%d %d",&pos[i].x,&pos[i].y); 68 hash_insert(pos[i].x, pos[i].y); 69 } 70 int ans = 0; 71 for(i = 0; i < n-1; i++) 72 { 73 for(j = i+1; j < n; j++) 74 { 75 int x1 = pos[i].x, y1 = pos[i].y; 76 int x2 = pos[j].x, y2 = pos[j].y; 77 int add_x = x1-x2,add_y = y1-y2; 78 int x3 = x1+add_y; 79 int y3 = y1-add_x; 80 int x4 = x2+add_y; 81 int y4 = y2-add_x; 82 if(find(x3,y3) && find(x4,y4)) 83 ans++; 84 85 x3 = x1-add_y; 86 y3 = y1+add_x; 87 x4 = x2-add_y; 88 y4 = y2+add_x; 89 if(find(x3,y3) && find(x4,y4)) 90 ans++; 91 } 92 } 93 printf("%d\n",ans/4); 94 } 95 return 0; 96 }