Squares--POJ 2002
1、题目类型:枚举,哈希表。
2、解题思路:(1)建立输入点集Arr[],并插入Hash表;(2)枚举所有线段利用Hash表寻找是否存在另外两点使其构成正方形;
3、注意事项:已知两点(a1,a2)和(b1,b2),有点(a1+(a2-b2), a2-(a1-b1))和点(b1+(a2-b2), b2-(a1-b1))可以构成一个正方形。
4、实现方法:
#include<iostream>
#include<cmath>
using namespace std;
double const e=0.00000001;
struct Hash{
int num;
Hash *next;
Hash()
{
num=-1;
next=NULL;
}
Hash(int num)
{
this->num=num;
next=NULL;
}
};
struct TPoint{
int x,y;
};
TPoint Arr[1010];
Hash table[40001];
//寻找点是否存在
bool FindPoint(Hash table[],double x,double y)
{
int tmp=fabs(x+y);
if(table[tmp].num!=-1)
{
Hash *p=&table[tmp];
while(p!=NULL)
{
if(fabs(Arr[p->num].x-x)<e && fabs(Arr[p->num].y-y)<e)
return true;
p=p->next;
}
return false;
}
return false;
}
int main()
{
int n,i,j,tmp,cnt;
while(cin>>n && n)
{
if(n==0)
break;
memset(table,NULL,sizeof(table));
for(i=0;i<n;++i)
{
cin>>Arr[i].x>>Arr[i].y;
tmp=abs(Arr[i].x+Arr[i].y);
if(table[tmp].num==-1)
table[tmp].num=i;
else
{
Hash *p=table+tmp;
while(p->next!=NULL)
p=p->next;
p->next=new Hash(i);
}
}
cnt=0;
for(i=0;i<n;i++)
for(j=i+1;j<n;j++)
{
if(FindPoint(table,(double)(Arr[i].x+Arr[j].x+Arr[j].y-Arr[i].y)/2,
(double)(Arr[i].x-Arr[j].x+Arr[i].y+Arr[j].y)/2)
&& FindPoint(table,(double)(Arr[i].x+Arr[j].x-Arr[j].y+Arr[i].y)/2,
(double)(-Arr[i].x+Arr[j].x+Arr[i].y+Arr[j].y)/2))
++cnt;
}
cout<<cnt/2<<endl;
}
return 1;
}