您的位置:首页 > 其它

POJ 2002 - Squares(hash)

2015-02-21 20:54 357 查看
题目:http://poj.org/problem?id=2002

题意:

给出n个点的坐标(x,y),求出能组成正方形的个数。

思路:

首先应该知道的是知道正方形一条边上的两个点 (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)

然后利用hash[] 记录散点集。
准备工作做完之后,枚举两个点,求出另外两个点,看是否存在。

CODE:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;
const int maxn = 20007;
struct Point {
int x, y;
bool operator < (const Point & a) const {
if(x == a.x) return y < a.y;
return x < a.x;
}
}pot[maxn];
int n, next[maxn], head[maxn], m;

void inset(Point a)
{
int key = (a.x*a.x + a.y*a.y) % maxn;
next[m] = head[key];
pot[m].x = a.x;
pot[m].y = a.y;
head[key] = m++;
}
int Find(int x, int y)
{
int key = (x*x + y*y) % maxn;
for(int i = head[key]; i !=-1; i = next[i]) {
if(pot[i].x == x && pot[i].y == y) return i;
}
return -1;
}
int main()
{
//freopen("in", "r", stdin);
while(~scanf("%d", &n)) {
if(n == 0) break;
memset(head, -1, sizeof(head));
memset(next, 0, sizeof(next));
m = 1005;
for(int i = 0; i < n; ++i) {
scanf("%d%d", &pot[i].x, &pot[i].y);
inset(pot[i]);
}

int x1, y1, x2, y2;
int ans = 0;
for(int i = 0; i < n; ++i) {
for(int j = 0; j < n; ++j) {
if(i != j) {
x1 = pot[i].x - pot[j].y + pot[i].y;
y1 = pot[i].y + pot[j].x - pot[i].x;
if(Find(x1, y1) == -1) continue;
x2 = pot[j].x - pot[j].y + pot[i].y;
y2 = pot[j].y + pot[j].x - pot[i].x;
if(Find(x2, y2) == -1) continue;
ans++;
}

}
}
printf("%d\n", ans/4);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  POJ