题意:给定n个点
下面n行表示n个坐标,问最多能组成几个正方形
这里正方形是:遍历其中2个点,判断另外2个点是否存在
已知: (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)
判断其他2个点用的是multimap(关于多重映射的multimap可以戳这里了解一下)
mark:
#include <stdio.h>
#include <string.h>
#include <map>
#include <iostream>
using namespace std;
struct node{
int x,y;
}P[1010];
bool Hash[99999];
multimap <int ,int> m;//multimap的创建
multimap<int,int>::iterator iter;
int Have(node a){
int k=(a.x*a.x+a.y*a.y)%99991;
if(!Hash[k])return false;
else
{
int num=m.count(k);
iter=m.find(k);
while(num--)
{
int sec=(*iter).second;
if(P[sec].x==a.x && P[sec].y==a.y)return sec;
iter++;
}
return false;
}
}
int Find(int i,int j){
/*已知: (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)
*/
int ans=0;
node a=P[i],b=P[j],c,d;
c.x=a.x+(a.y-b.y),c.y=a.y-(a.x-b.x);
d.x=b.x+(a.y-b.y),d.y=b.y-(a.x-b.x);
if(Have(c)&&Have(d))ans++;
c.x=a.x-(a.y-b.y),c.y=a.y+(a.x-b.x);
d.x=b.x-(a.y-b.y),d.y=b.y+(a.x-b.x);
if(Have(c)&&Have(d))ans++;
return ans;
}
void Insert(int num){
int k=(P[num].x*P[num].x+P[num].y*P[num].y)%99991;//平方同余法
Hash[k]=true;
m.insert(pair<int,int>(k,num));//插入
}
int main(){
int n,i,j;
while(scanf("%d",&n),n){
memset(Hash,0,sizeof(Hash));
m.clear();
for(i=1;i<=n;i++){
scanf("%d %d",&P[i].x,&P[i].y);
Insert(i);
}
int ans=0;
for(i=1;i<n;i++)
for(j=i+1;j<=n;j++)
ans+=Find(i,j);//若i,j是正方形的邻边且存在与之配对的点,则有一个正方形
printf("%d\n",ans/4);//每个正方形的边都将这个正方形计算过一次
}
return 0;
}
//2002