您的位置:首页 > 其它

poj 2002 Squares

2011-03-09 11:00 176 查看
这题学习了hash,碰撞的链表解决。

感觉这题的搜索策略还是值得考虑的(题目的思想是:根据其中的两点为边,求出另外两点的坐标,通过hash,查找是否存在这两点),我们对所有的点根据x排序,如果x相同,则根据y排序,排序之后,一个正方形的四个点肯定有先后次序,分别标为1,2,3,4,则1 2,1 3,2 3,3 4,这四个组合都会搜到同一个正方形。我们再考虑,我们只搜第二个点的xy都比第一个点大的组合,则只剩下1 2 ,3 4组合,推公式时,这两个组合的公式是不一样的。但是当正方形的边平行于坐标轴时,这两个组合的公式就是一样了,那么可以删掉其中一组就可以了。

#include<iostream>
#include<cmath>
#include<cstdlib>
using namespace std;
#define N 40005
#define maxn 1005
struct Hash
{
int index;
Hash *next;
Hash()
{
index=-1,next=NULL;
}
Hash(int i)
{
index=i,next=NULL;
}
};
struct point
{
int x,y;
};
point p[maxn];
bool found(Hash *h,int x,int y)
{
int temp=abs(x+y);
if(h[temp].index==-1)
return false;
Hash *ptr=&h[temp];
while(ptr!=NULL)
{
if(p[ptr->index].x==x&&p[ptr->index].y==y)
return true;
ptr=ptr->next;
}
return false;
}
void init(int n,Hash *h)
{
int temp,i;
Hash *ptr;
for(i=0;i<n;i++)
{
temp=abs(p[i].x+p[i].y);
if(h[temp].index==-1)
h[temp].index=i;
else
{
ptr=&h[temp];
while(ptr->next)
ptr=ptr->next;
ptr->next=new Hash(i);
}
}
return ;
}
int cmp(const void *a,const void *b)
{
point p1=*(point*)a;
point p2=*(point*)b;
if(p1.x<p2.x)
return -1;
if(p1.x==p2.x&&p1.y<p2.y)
return -1;
return 1;
}
int main()
{
int n,i,j,xx,yy,x1,y1,x2,y2,sum;
while(scanf("%d",&n),n)
{
Hash ys
;
sum=0;
for(i=0;i<n;i++)
scanf("%d%d",&p[i].x,&p[i].y);
qsort(p,n,sizeof(p[0]),cmp);
init(n,ys);
for(i=0;i<n;i++)
for(j=i+1;j<n;j++)
{
if(p[j].y>=p[i].y)
{
if(p[j].x==p[i].x)
continue;
xx=p[j].x-p[i].x;
yy=p[j].y-p[i].y;
x1=p[i].x+yy;
y1=p[i].y-xx;
x2=p[j].x+yy;
y2=p[j].y-xx;
if(found(ys,x1,y1)&&found(ys,x2,y2))
sum++;
}
}
printf("%d/n",sum);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: