POJ 2002 Squares Hash

题意:给定n个点

下面n行表示n个坐标,问最多能组成几个正方形

这里正方形是:遍历其中2个点,判断另外2个点是否存在

//下面的公式来自http://blog.csdn.net/lyy289065406/article/details/6647405

已知: (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



你可能感兴趣的:(hash,poj)