/**
* poj 2002 排序+哈希
* 首先要有一个正确的大方向,就是取两个点,利用公式给出另外两个点,并搜索这另外的两个点是否存在
* 大方向有了,首先是确定另外两个点的方法,随意取点,可能组出多个正方形,判断的时候会取多次,这就浪费了很多运算量
* 吸取了别人代码的经验,首先将点先x后y升序排列,然后对于i<j,只考虑yi>=yj的点。有所改进的是,我们这里不需要对xi==xj的情况多做判断,这是因为排序之后,不可能有xi==xj,yi>=yj的情况出现
* 这样,得到两点取另两点的方向就可以放在第一象限方向(正方向)了
* 下面是哈希,其实是就是哈希的原理,只是我是第一次手写哈希的构造和搜索,所以写出来很蹩脚。而且因为最开始,多轮运算之间忘了重新初始化HASH表,WA了好多次
* 既然是第一次写哈希,就把哈希的原理也说一下吧.简单地说,我们用数组索引指向数据,而搜索的时候是用数据查找索引,哈希就是另外构建了一张表,将数据通过函数计算出一个下标,将原数组的索引作为值,以链表的形式存起来
* 对于不可能出现哈希值重复的情况,就不需要使用链表,而像题目中这种情况,肯定会有重复的,就需要用链表来在重复的情况下进行查找。如何将整个数据范围尽量平摊到哈希表长度上,就是哈希函数选取的关键了
* 我这里是随便取的,找了一个素数7993,取((abs(x)+1)*(abs(y)+1))%7993作为哈希函数,还好,344ms就过了
* 这道题好像还有一种二分搜索的做法,我这里就不尝试了
*/
#include <cstdio>
#include <iostream>
#include <cstdlib>
using namespace std;
const int MAX_NUM = 1001;
const int PRIME = 7993;
struct point{
int x;
int y;
} p[MAX_NUM];
struct node{
int index;
node* next;
node(){
index = -1;
next = NULL;
}
node(int i){
index = i;
next = NULL;
}
};
int abs(int i){
return (i>=0) ? i : -1*i;
}
int cmp(const void* a,const void* b){
point *p1=(point*)a,*p2=(point*)b;
if(p1->x != p2->x){
return p1->x - p2->x;
}
else{
return p1->y - p2->y;
}
}
bool find(node* hash,int x,int y){
int key = ((abs(x)+1) * (abs(y)+1)) % PRIME;
node *pn;
if(hash[key].index < 0){
return false;
}
else{
pn = &hash[key];
while(pn != NULL){
if(p[pn->index].x == x && p[pn->index].y == y){
return true;
}
else{
pn = pn->next;
}
}
return false;
}
}
int main(){
int n,res;
scanf("%d",&n);
while(n!=0){
node hash[PRIME];
int key;
node *pp;
for(int i=0;i<n;++i){
scanf("%d%d",&p[i].x,&p[i].y);
}
qsort(p,n,sizeof(point),cmp);
for(int i=0;i<n;++i){
//construct hash table
key = ((abs(p[i].x)+1) * (abs(p[i].y)+1)) % PRIME;
if(hash[key].index == -1){
hash[key].index = i;
}
else{
pp = &hash[key];
while(pp->next != NULL){
pp = pp->next;
}
pp->next = new node(i);
}
}
res = 0;
int x1,x2,y1,y2,x3,x4,y3,y4,ydiff,xdiff;
for(int i=0;i<n;++i){
x1 = p[i].x;
y1 = p[i].y;
for(int j=i+1;j<n;++j){
if(p[j].y <= p[i].y){
x2 = p[j].x;
y2 = p[j].y;
ydiff = abs(y1-y2);
xdiff = abs(x1-x2);
x3 = x1 + ydiff;
x4 = x2 + ydiff;
y3 = y1 + xdiff;
y4 = y2 + xdiff;
if(find(hash,x3,y3) && find(hash,x4,y4)){
++res;
}
}
}
}
printf("%d\n",res);
scanf("%d",&n);
}
return 0;
}
poj2002 排序+哈希
最新推荐文章于 2021-10-05 21:17:08 发布