题意,给出平面上n个点,求能形成的正方形个数
挺简单的题,用两个点来枚举。首先把所有的点用哈希函数处理后存起来,然后枚举两个点,以这两点为正方形同一边的两顶点,求出另外顶点的位置,然后查找这两个点是否存在即可。
这题用的静态链表做的,当成练习。同时注意下哈希函数,发同用x*x+y*y会TLE,毕竟也可能会有挺多相同的,然后为了区别x和y的正负性,把哈希函数改成x*x+y*y+x+y,我觉得这个答案一定不小于0的,所以没取绝对值,结果RE了。。。百思不得期解Orz
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
#define MAXN 1005
#define PRIME 21911
#define SIZE 1500
typedef struct hashtable{
int x, y;
int next;
}Hashtable;
Hashtable hashlist[SIZE];
int avail;
int hashs[PRIME+5];
void init(){
avail=1;
memset(hashs, -1, sizeof(hashs));
}
int getnode(){
int p;
p=avail;avail++;
return p;
}
void insert(int p, int x, int y){
hashlist[p].x=x;hashlist[p].y=y;
hashlist[p].next=-1;
}
int hashf(int x, int y){
int ret;
ret=x*x+y*y+x+y;
ret*=31;
if(ret<0)ret=-ret;
ret%=PRIME;
return ret;
}
void update(int key, int x, int y){
if(hashs[key]==-1){
hashs[key]=getnode();
insert(hashs[key], x, y);
}
else{
int pos=hashs[key];
while(hashlist[pos].next!=-1){
pos=hashlist[pos].next;
}
int cur=getnode();
hashlist[pos].next=cur;
insert(cur, x, y);
}
}
bool isthesame(Hashtable a, int x, int y){
if(a.x==x&&a.y==y)return true;
else return false;
}
bool isexist(int x, int y){
int key=hashf(x, y);
if(hashs[key]==-1)return false;
int pos=hashs[key];
while(hashlist[pos].next!=-1){
if(isthesame(hashlist[pos], x, y))
return true;
pos=hashlist[pos].next;
}
if(isthesame(hashlist[pos], x, y))
return true;
return false;
}
struct node{
int x, y;
void in(int a, int b){
x=a;y=b;
}
}coor[MAXN];
int main(){
int n;
int x, y;
while(scanf("%d", &n), n){
init();
for(int i=0;i<n;i++){
scanf("%d%d", &x, &y);
coor[i].in(x, y);
update(hashf(x, y), x, y);
}
int xa, ya, xb, yb;
int xt, yt;
int ans=0;
for(int i=0;i<n;i++){
for(int j=i+1;j<n;j++){
xt=coor[i].x-coor[j].x;
yt=coor[i].y-coor[j].y;
xa=coor[i].x+yt;ya=coor[i].y-xt;
xb=coor[j].x+yt;yb=coor[j].y-xt;
if(isexist(xa, ya)&&isexist(xb, yb))ans++;
xa=coor[i].x-yt;ya=coor[i].y+xt;
xb=coor[j].x-yt;yb=coor[j].y+xt;
if(isexist(xa, ya)&&isexist(xb, yb))ans++;
}
}
ans>>=2;
cout<<ans<<endl;
}
return 0;
}