Time Limit: 3500MS | Memory Limit: 65536K | |
Total Submissions: 8065 | Accepted: 2718 |
Description
Input
Output
Sample Input
4 1 0 0 1 1 1 0 0 9 0 0 1 0 2 0 0 2 1 2 2 2 0 1 1 1 2 1 4 -2 5 3 7 0 0 5 2 0
Sample Output
1 6 1
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
const int HASHING=2100;//important
const int BLOCK=20001;//考虑坐标为负的情况
int hash_table[HASHING+1];
int hash(int x)//构建哈希表
{
int ret;
ret=x%HASHING;
while(hash_table[ret]!=-1&&hash_table[ret]!=x) ret=(ret+1)%HASHING;
hash_table[ret]=x;
return ret;
}//important
int vis[HASHING+10][HASHING+10];
struct Point
{
int x,y;
};
Point a[1100];
double x[3],y[3];
double _fabs(double x){return x>0?x:-x;}
void cal(int i,int j)//已知正方形对角线坐标,求其余两个顶点坐标
{
double x0=(double)(a[i].x+a[j].x)/2,y0=(double)(a[i].y+a[j].y)/2;
if((a[j].y-a[i].y)*(a[j].x-a[i].x)>0)
{
x[1]=x0-_fabs(a[j].y-a[i].y)/2;
x[2]=x0+_fabs(a[j].y-a[i].y)/2;
y[1]=y0+_fabs(a[j].x-a[i].x)/2;
y[2]=y0-_fabs(a[j].x-a[i].x)/2;
}
else
{
x[1]=x0-_fabs(a[j].y-a[i].y)/2;
x[2]=x0+_fabs(a[j].y-a[i].y)/2;
y[1]=y0-_fabs(a[j].x-a[i].x)/2;
y[2]=y0+_fabs(a[j].x-a[i].x)/2;
}
}
int main()
{
int n;
while(scanf("%d",&n)==1&&n)
{
memset(hash_table,-1,sizeof(hash_table));//初始化哈希表 important
memset(vis,0,sizeof(vis));
for(int i=0;i<n;i++)
{
scanf("%d%d",&a[i].x,&a[i].y);
vis[hash(a[i].x+BLOCK)][hash(a[i].y+BLOCK)]=1;
}
long long cnt=0;
for(int i=0;i<n;i++)
{
for(int j=i+1;j<n;j++)
{
cal(i,j);
int t1=(int)x[1],t2=(int)x[2],t3=(int)y[1],t4=(int)y[2];//(t1,t3),(t2,t4)
if(t1!=x[1]||t2!=x[2]||t3!=y[1]||t4!=y[2])continue;
if(vis[hash(t1+BLOCK)][hash(t3+BLOCK)]&&vis[hash(t2+BLOCK)][hash(t4+BLOCK)]) cnt++;
//if(i==0&&j==3) cout<<t1<<"..."<<t2<<"..."<<t3<<"..."<<t4<<endl;
}
}
cout<<cnt/2<<endl;
}
return 0;
}
/*
先将读入的n个点的坐标按照其x坐标作为关键值进行hash,枚举每两个不同的点,将他们作为某个正方形的对角线,
算出两外的两个点,然后对于新算出的两个点的x坐标进行hash查找,对于x相同的点,判断y是否也相同,若相同,
则继续hash另一个点的坐标,若两次都能找到则正方形个数加1。在哈希判断时若找到相同的则直接退出本次查找,
否则一直查找到链表的末尾,表示没有以该两点作为对角线的正方形。
*/