POJ 2002 - Squares(hash)

来源:互联网 发布:深圳it外包公司 编辑:程序博客网 时间:2024/04/30 18:25

题目: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;}


0 0
原创粉丝点击