题目大意
给你一些点,求从其中取出4个点能组成平行四边形的点对数。
题目分析
一开始想的是枚举两个点,然后储存可以用来算斜率与长度的数值,如果一样就可以组成平行四边形…but…如果这4个点在同一条直线上呢啊喂?连样例都过不了的啊喂。
于是看了一下网上的题解,枚举两个点,算中点,因为对角线互相平分的四边形是平行四边形…
好吧…
代码
#include<algorithm>
#include<iostream>
#include<cstring>
#include<climits>
#include<cstdio>
using namespace std;
#define LL long long
LL read(){
LL q=0,w=1;char ch=' ';
while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
if(ch=='-')w=-1,ch=getchar();
while(ch>='0'&&ch<='9')q=q*10+(LL)(ch-'0'),ch=getchar();
return q*w;
}
const int N=1005;
int T,tot,n;LL ans,mod=999997;
LL x[N],y[N];
int h[1000000],ne[N*N];
LL xx[N*N],yy[N*N],num[N*N];//数组要开n*n
void add(LL a,LL b){
LL kl=(a*a%mod+b)%mod;
if(kl<0)kl=-kl;//注意哈希值为负数
for(int i=h[kl];i!=-1;i=ne[i])//链式哈希
if(xx[i]==a&&yy[i]==b)
{ans+=num[i],++num[i];return;}
++tot;xx[tot]=a,yy[tot]=b,num[tot]=1,ne[tot]=h[kl],h[kl]=tot;
}
int main()
{
int i,j;
T=read();
while(T--){
n=read();
memset(h,-1,sizeof(h));tot=0;
for(i=1;i<=n;++i)x[i]=read(),y[i]=read();
ans=0;
for(i=1;i<=n;++i)
for(j=i+1;j<=n;++j)add(x[i]+x[j],y[i]+y[j]);
printf("%lld\n",ans);
}
return 0;
}