Squares
题目链接:http://poj.org/problem?id=2002
~~~Hash 求二维坐标系里正方形的个数
题目大意:给你n个坐标点,然后要计算出这些点能构成多少不一样的正方形。
题目思路:首先输入的时候将每个点通过调用hash函数求出它的hash值并将点存入对应的hash数组中,如果遇到有冲突则用链表链起来 ,因此定义hash数组时应该是个结构体数组,每个元素要包含点的信息和一个next指针用来避免冲突。接下来就是枚举两个顶点,根据这两个顶点计算出要满足正方形需要的剩下两个顶点,然后判断该顶点是否在hash数组中存在,如果都存在则方案数+1,最后所得方案数要除以4,因为一个正方形有四条边,每条边都会对这个正方形判断一次。
注意的问题:
hash函数有多种,看个人习惯。
查找链表里的点时定义的Hash指针是不用初始化的(避免超时和超内存)
判断剩下两个点时,如果第一个点都不存在,那么第二个点就不需要判断了(避免超时)
AC代码如下;
#include<iostream>
#include<malloc.h>
#include<cstdio>
#include<cstring>
using namespace std;
#define N 1005
struct Point{
int x;
int y;
}po[N];
struct Hash{
Point p;
Hash *next;
}ha[N];
int Key(Point p){
return (p.x*p.x+p.y*p.y)%N;
}
void in(Point p){
int key=Key(p);
//Hash *q=new Hash();
Hash *q=(Hash *)malloc(sizeof(Hash));
q->p=p;
q->next=ha[key].next;
ha[key].next=q;
}
int Search(Point t1,Point t2){
int ok=0,key;
key=Key(t1);
Hash *q1=ha[key].next;
while(q1){
if(q1->p.x==t1.x&&q1->p.y==t1.y){
ok++;
break;
}
q1=q1->next;
}
if(ok==0) return 0;
key=Key(t2);
Hash *q2=ha[key].next;
while(q2){
if(q2->p.x==t2.x&&q2->p.y==t2.y){
ok++;
break;
}
q2=q2->next;
}
if(ok==2) return 1;
else return 0;
}
int main(){
int n;
while(scanf("%d",&n)&&n){
memset(ha,0,sizeof(ha));
for(int i=0;i<n;i++){
scanf("%d%d",&po[i].x,&po[i].y);
in(po[i]);
}
int ans=0;
for(int i=0;i<n-1;i++){
for(int j=i+1;j<n;j++){
Point t1,t2;
t1.y=po[i].y+po[j].x-po[i].x;
t1.x=po[i].x+po[i].y-po[j].y;
t2.y=po[j].y+po[j].x-po[i].x;
t2.x=po[j].x+po[i].y-po[j].y;
ans+=Search(t1,t2);
t1.y=po[i].y-(po[j].x-po[i].x);
t1.x=po[i].x-(po[i].y-po[j].y);
t2.y=po[j].y-(po[j].x-po[i].x);
t2.x=po[j].x-(po[i].y-po[j].y);
ans+=Search(t1,t2);
}
}
printf("%d\n",ans/4);
}
return 0;
}