地址:http://acm.bit.edu.cn/mod/programming/view.php?a=519
平面上有n个点,问这些点能形成几个正方形。(n<1000)
只要枚举两个点作为正方形的两个顶点(相邻或者相对都行),从而算出另两个顶点的坐标,然后查找这两个坐标是否存在于点集内就可以啦。因为枚举需要o(n^2),查找效率就必须是o(logn)不然超时啦~可以用哈希、二分查找等等方法加速查找。我是偷师了伟神用了set容器。注意set容器需要定义元素间的大小关系,重载一下<运算符即可。
还要注意除掉这样枚举每个正方形被枚举到的次数。
#include<iostream>
#include<algorithm>
#include<cmath>
#include<set>
using namespace std;
typedef struct POINT
{
double x,y;
}point;
point p[1005];
typedef struct LINE
{
point a,b;
}line;
point operator + (point a,point b)
{
point c;
c.x = a.x + b.x , c.y = a.y + b.y;
return c;
}
point operator - (point a,point b)
{
point c;
c.x = a.x - b.x , c.y = a.y - b.y;
return c;
}
bool operator < (point a,point b)
{
if(a.x!=b.x) return a.x<b.x;
else return a.y<b.y;
}
int main()
{
int n,i,j;
double temp;
point t1,t2,mid,vec;
while(scanf("%d",&n),n)
{
int ans=0;
set<point>s;
for(i=0;i<n;i++)
{
scanf("%lf%lf",&p[i].x,&p[i].y);
s.insert(p[i]);
}
for(i=0;i<n;i++)
{
for(j=0;j<i;j++)
{
mid=p[i]+p[j];
mid.x/=2,mid.y/=2;vec=p[j]-mid;
temp=vec.x,vec.x=-vec.y,vec.y=temp;
t1=mid+vec;
t2=mid-vec;
if(s.count(t1)&&s.count(t2)) ans++;
}
}
printf("%d\n",ans/2);
}
return 0;
}