POJ 2002 Squares (哈希表)

来源:互联网 发布:新人如何把淘宝做起来 编辑:程序博客网 时间:2024/05/21 13:57

题意:

在二维坐标上给一堆不重复的点,问能组成多少个正方形.



解题思路:

一开始的方法是记录每条边的距离,找出相同距离的边,然后想办法判断这两条边是不是一个正方形的对角线,用叉积相乘等于零以及中点相等两个点来判断,这样做答案正确,但是明显超时,总共有50W条边,每找到一组重复边再去判断两两之间是不是满足关系,复杂度最坏的情况相当于O(N^3),可怕...


然后换了一种思路,终于正确了.


记录每一条边,去判断这条边上面和下面满足组成正方形的边中的两个点是否存在,存点的方式如果直接开二维数组的话肯定不行,点的范围在20000,开不下,所以想到构造哈希函数,

即:hash[key]=(x*x+y*y)%mod.mod取不大于100*坐标数量的素数,之所以乘100是因为开更大的存储空间可以减少冲突,从而降低查询的时间.

所以这就成为一个简单的哈希表查询问题了

最后得到的答案要除以4,因为一个正方形的四条边都被查询过.


代码 :

#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>using namespace std;struct node{    int x;    int y;    node* next;};int k;struct node* has[99991];const int mod = 99991;struct p{int x;int y;} b[10001234];void inse(int x){    int targ=(b[x].x*b[x].x+b[x].y*b[x].y)%mod;    node*q, *t;    if(has[targ])    {        t=q=has[targ];        while(q)        {            t=q;            q=q->next;        }        t->next=(node*)malloc(sizeof(node));        t->next->x=b[x].x;        t->next->y=b[x].y;        t->next->next=NULL;    }    else    {        has[targ]=(node*)malloc(sizeof(node));        has[targ]->x=b[x].x;        has[targ]->y=b[x].y;        has[targ]->next=NULL;    }}int findd(int x){    int targ=(b[x].x*b[x].x+b[x].y*b[x].y)%mod;    node*q;    q=has[targ];    while(q)    {        if(q->x==b[x].x && q->y==b[x].y)        {            return 1;        }        q=q->next;    }    return 0;}long long pd(int x, int y){    long long ret=0;if (b[x].y < b[y].y){swap(x,y);}int x1, x2, y1, y2;int dx, dy;dx = abs(b[x].x - b[y].x);dy = abs(b[x].y - b[y].y);if (b[y].x < b[x].x){x1 = b[y].x - dy;y1 = b[y].y + dx;x2 = b[x].x - dy;y2 = b[x].y + dx;}else{x1 = b[y].x + dy;y1 = b[y].y + dx;x2 = b[x].x + dy;y2 = b[x].y + dx;}b[k].x=x1;b[k].y=y1;k++;b[k].x=x2;b[k].y=y2;if(findd(k) && findd(k-1))ret++;k++;{dx = -abs(b[x].x - b[y].x);dy = -abs(b[x].y - b[y].y);if (b[y].x < b[x].x){x1 = b[y].x - dy;y1 = b[y].y + dx;x2 = b[x].x - dy;y2 = b[x].y + dx;}else{x1 = b[y].x + dy;y1 = b[y].y + dx;x2 = b[x].x + dy;y2 = b[x].y + dx;}b[k].x=x1;b[k].y=y1;k++;b[k].x=x2;b[k].y=y2;if(findd(k) && findd(k-1))ret++;k++;}    return ret;}int main(){int n;while (~scanf("%d", &n)){int i, j;if(n==0)break;memset(has, 0, sizeof(has));for (i = 1; i <= n; i++){scanf("%d%d", &b[i].x, &b[i].y);inse(i);}k=i;long long ans = 0;for (i = 1; i <= n; i++){for (j = i + 1; j <= n; j++){ans += pd(i, j);}}printf("%lld\n", ans/4);}return 0;}


0 0