您的位置:首页 > 其它

POJ 2002 几何+hash

2015-06-01 19:46 363 查看
题目大意:

给定1000个点,寻找有多少组四点对能组成正方形

这里的题目跟上一道做的找平行四边形类似但想法却又不相同的方法

这里找任意2个点形成的一条边,那么可以根据这两个点,找到能和他们组成正方形剩下的两个点的位置,根据hash表去搜索,如果这两个位置存在自己需要的点,说明这种方案可行

添加查找均交给hash表,这样可以实现O(n*n)的复杂度

最后因为每个正方形因为有4条边被访问了4次,所以总的答案要除以4

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;
#define N 1010
#define MOD 1000007
int head[MOD+2] , k;

struct Point{
int x , y;
Point(int x=0 , int y=0):x(x),y(y){}
bool operator==(const Point &m)const{
return x==m.x&&y==m.y;
}
void input(){scanf("%d%d" , &x , &y);}
void print(){cout<<x<<" "<<y<<endl;}
}p
;

struct HashNode{
int id , next;
}_hash
;

void insert(int i)
{
int v = (p[i].x*p[i].x+p[i].y*p[i].y)%MOD;
_hash[k].id = i , _hash[k].next = head[v];
head[v] = k++;
}

bool find(Point a)
{
int v = (a.x*a.x+a.y*a.y)%MOD;
for(int i=head[v] ; ~i ; i=_hash[i].next){
if(p[_hash[i].id] == a) return true;
}
return false;
}

int main()
{
#ifndef ONLINE_JUDGE
freopen("a.in" , "r" , stdin);
#endif // ONLINE_JUDGE
int n;
while(scanf("%d" , &n) , n)
{
memset(head , -1 , sizeof(head));
k = 0;
for(int i=1 ; i<=n ; i++){
p[i].input();
insert(i);
}
int ret = 0;
for(int i=1 ; i<=n ; i++){
for(int j=i+1 ; j<=n ; j++){
int dy = p[j].y-p[i].y;
int dx = p[j].x-p[i].x;
Point p1 = Point(p[i].x+dy , p[i].y-dx);
Point p2 = Point(p[j].x+dy , p[j].y-dx);
if(find(p1) && find(p2)) ret++;
p1 = Point(p[i].x-dy , p[i].y+dx);
p2 = Point(p[j].x-dy , p[j].y+dx);
if(find(p1) && find(p2)) ret++;
}
}
printf("%d\n" , ret/4);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: