题目大意:
给定1000个点,寻找有多少组四点对能组成正方形
这里的题目跟上一道做的找平行四边形类似但想法却又不相同的方法
这里找任意2个点形成的一条边,那么可以根据这两个点,找到能和他们组成正方形剩下的两个点的位置,根据hash表去搜索,如果这两个位置存在自己需要的点,说明这种方案可行
添加查找均交给hash表,这样可以实现O(n*n)的复杂度
最后因为每个正方形因为有4条边被访问了4次,所以总的答案要除以4
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 6 using namespace std; 7 #define N 1010 8 #define MOD 1000007 9 int head[MOD+2] , k; 10 11 struct Point{ 12 int x , y; 13 Point(int x=0 , int y=0):x(x),y(y){} 14 bool operator==(const Point &m)const{ 15 return x==m.x&&y==m.y; 16 } 17 void input(){scanf("%d%d" , &x , &y);} 18 void print(){cout<<x<<" "<<y<<endl;} 19 }p[N]; 20 21 struct HashNode{ 22 int id , next; 23 }_hash[N]; 24 25 void insert(int i) 26 { 27 int v = (p[i].x*p[i].x+p[i].y*p[i].y)%MOD; 28 _hash[k].id = i , _hash[k].next = head[v]; 29 head[v] = k++; 30 } 31 32 bool find(Point a) 33 { 34 int v = (a.x*a.x+a.y*a.y)%MOD; 35 for(int i=head[v] ; ~i ; i=_hash[i].next){ 36 if(p[_hash[i].id] == a) return true; 37 } 38 return false; 39 } 40 41 int main() 42 { 43 #ifndef ONLINE_JUDGE 44 freopen("a.in" , "r" , stdin); 45 #endif // ONLINE_JUDGE 46 int n; 47 while(scanf("%d" , &n) , n) 48 { 49 memset(head , -1 , sizeof(head)); 50 k = 0; 51 for(int i=1 ; i<=n ; i++){ 52 p[i].input(); 53 insert(i); 54 } 55 int ret = 0; 56 for(int i=1 ; i<=n ; i++){ 57 for(int j=i+1 ; j<=n ; j++){ 58 int dy = p[j].y-p[i].y; 59 int dx = p[j].x-p[i].x; 60 Point p1 = Point(p[i].x+dy , p[i].y-dx); 61 Point p2 = Point(p[j].x+dy , p[j].y-dx); 62 if(find(p1) && find(p2)) ret++; 63 p1 = Point(p[i].x-dy , p[i].y+dx); 64 p2 = Point(p[j].x-dy , p[j].y+dx); 65 if(find(p1) && find(p2)) ret++; 66 } 67 } 68 printf("%d\n" , ret/4); 69 } 70 }
我还在坚持,我还未达到我所想,梦~~一直在