POJ-2002 Squares,哈希模板+数学公式!

时间:2020-12-24 07:51:05

                                                       Squares

题意:二维坐标轴给出n个点求有多少个正方形。

要是平时做比赛的话毫无疑问会想到用二分去写这道题,但毕竟出现在hash专题里,所以自然用hash去攻克,但是完全没有思路,于是,,网上找了题解,让我感叹的是我们做hash的题怎么知道用哪种hash函数呢。。这道题以坐标平方和再对hash数组大小取余,这样离散化感觉有点钻数据空子,但hash是有处理冲突的能力的,存在冲突怎么办呢,我们可以用链表的形式建立联系,直接在链表中查找就可以了。

用两层循环枚举然后在hash表中查找另外两个点是否存在,所以这题还有一个很重要的数学公式,那就是:

已知: (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表中查找。

struct hashmap
{
int x,y;
hashmap *next;
hashmap()
{
next=NULL;
}
}*h[N];
struct node
{
int x,y;
}a[N];
void insert(int x,int y)
{
int key=(x*x+y*y)%N;
if(!h[key])
{
hashmap *tmp=new hashmap();
tmp->x=x,tmp->y=y;
h[key]=tmp;
}
else
{
hashmap *tmp=h[key];
while(tmp->next) tmp=tmp->next;
tmp->next=new hashmap();
tmp->next->x=x,tmp->next->y=y;
}
}
bool find(int x,int y)
{
int key=(x*x+y*y)%N;
hashmap *tmp=h[key];
while(tmp)
{
if(tmp->x==x&&tmp->y==y) return true;
tmp=tmp->next;
}
return false;
}
int main()
{
int n;
while(~scanf("%d",&n)&&n)
{
memset(h,0,sizeof(h));
for(int i=0;i<n;i++)
{
scanf("%d%d",&a[i].x,&a[i].y);
insert(a[i].x,a[i].y);
}
int ans=0;
for(int i=0;i<n;i++)
for(int j=i+1;j<n;j++)
{
int x1=a[i].x+a[i].y-a[j].y,y1=a[i].y-a[i].x+a[j].x;
int x2=a[j].x+a[i].y-a[j].y,y2=a[j].y-a[i].x+a[j].x;
if(find(x1,y1)&&find(x2,y2)) ans++;
x1=a[i].x+a[j].y-a[i].y,y1=a[i].y+a[i].x-a[j].x;
x2=a[j].x+a[j].y-a[i].y,y2=a[j].y+a[i].x-a[j].x;
if(find(x1,y1)&&find(x2,y2)) ans++;
}
printf("%d\n",ans/4);
}
return 0;
}