POJ-2002 Squares---绕点旋转+Hash

题目链接:

https://vjudge.net/problem/POJ-2002

题目大意:

有一堆平面散点集,任取四个点,求能组成正方形的不同组合方式有多少。

相同的四个点,不同顺序构成的正方形视为同一正方形。

解题思路:

直接四个点四个点地枚举肯定超时的,不可取。

普遍的做法是:先枚举两个点(这两个点是正方形的一条边),通过数学公式得到另外2个点,使得这四个点能够成正方形。然后检查散点集中是否存在计算出来的那两个点,若存在,说明有一个正方形。

但这种做法会使同一个正方形按照不同的顺序被枚举了四次,因此最后的结果要除以4.

已知点(x1, y1),(x2, y2),可求出下面两种可能

求出另外两个点之后直接在不在hash表中(之前用二分一直超时)

关于点(x1, y1)绕点(x0, y0)逆时针旋转β度得到(x2, y2)的公式:

 

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<string>
  5 #include<map>
  6 #include<set>
  7 #include<cmath>
  8 #include<algorithm>
  9 #include<vector>
 10 #define lowbot(i) (i&(-i))
 11 //#define Rotate(a, b) node(a.x + a.y - b.y, a.y + b.x - a.x)
 12 using namespace std;
 13 typedef long long ll;
 14 const int maxn = 1000 + 10;
 15 const int mod = 9973;
 16 struct node
 17 {
 18     int x, y;
 19     node(){}
 20     node(int x, int y):x(x), y(y){}
 21 };
 22 struct hashtable
 23 {
 24     int x, y;
 25     hashtable * next;
 26     hashtable()
 27     {
 28         next = 0;
 29     }
 30 };
 31 hashtable * Hash[mod];
 32 void Hash_Insert(node a)
 33 {
 34     int key = (a.x * a.x + a.y * a.y) % mod;
 35     if(!Hash[key])
 36     {
 37         hashtable * p = new hashtable;
 38         p->x = a.x;
 39         p->y = a.y;
 40         Hash[key] = p;
 41     }
 42     else
 43     {
 44         hashtable *p = Hash[key];
 45         while(p->next)p=p->next;
 46         hashtable* temp = new hashtable;
 47         temp->x = a.x;
 48         temp->y = a.y;
 49         p->next = temp;
 50     }
 51 }
 52 bool Find(node a)
 53 {
 54     int key = (a.x * a.x + a.y * a.y) % mod;
 55     if(!Hash[key])return false;
 56     else
 57     {
 58         hashtable * temp = Hash[key];
 59         while(temp)
 60         {
 61             if(temp->x == a.x && temp->y == a.y)
 62                 return true;
 63             temp = temp->next;
 64         }
 65     }
 66     return false;
 67 }
 68 node a[maxn];
 69 
 70 node Rotate(node a, node b)//点b绕着点a逆时针旋转90度的坐标
 71 {
 72     int x = (b.x - a.x) * 0 - (b.y - a.y) * 1 + a.x;
 73     int y = (b.x - a.x) * 1 + (b.y - a.y) * 0 + a.y;
 74     return node(x, y);
 75 }
 76 
 77 int main()
 78 {
 79     int n;
 80     while(scanf("%d", &n) != EOF && n)
 81     {
 82         memset(Hash, 0, sizeof(Hash));
 83         for(int i = 1; i <= n; i++)
 84         {
 85             scanf("%d%d", &a[i].x, &a[i].y);
 86             Hash_Insert(a[i]);
 87         }
 88         int ans = 0;
 89         node x, y;
 90         for(int i = 1; i <= n; i++)
 91         {
 92             for(int j = i + 1; j <= n; j++)
 93             {
 94                 x = Rotate(a[i], a[j]);
 95                 y = Rotate(x, a[i]);
 96                 if(Find(x) && Find(y))ans++;
 97                 //cout<<i<<" "<<j<<" "<<x.x<<" "<<x.y<<" "<<y.x<<" "<<y.y<<endl;
 98                 x = Rotate(a[j], a[i]);
 99                 y = Rotate(x, a[j]);
100                 if(Find(x) && Find(y))ans++;
101             }
102         }
103         printf("%d\n", ans / 4);
104     }
105     return 0;
106 }

 

posted @ 2018-04-26 09:17  _努力努力再努力x  阅读(247)  评论(0编辑  收藏  举报