4485ms,擦边球?。。。。下面还有一份优化版代码。。563ms
#include<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<cstdio>
const long long maxsize = 0x1fffff;
const int maxn = 1010;
using namespace std;
struct Point{
int x,y;
}p[maxn],mid[maxn*maxn];
int head[maxsize],next[maxn*maxn];
void init_hash(){
memset(head,-1,sizeof(head));
}
int get_hash(Point p){
return ((long long)p.x+p.y)&maxsize;
}
int insert(int i){
int h=get_hash(mid[i]);
//cout<<h<<endl;
int res=0;
int u=head[h];
while(u!=-1){
if(mid[u].x==mid[i].x&&mid[u].y==mid[i].y)
res++;
u=next[u];
}
next[i]=head[h];
head[h]=i;
return res;
}
int main()
{
int t;
cin>>t;
while(t--){
int n,i,ans=0,j;
cin>>n;
for(i=0;i<n;i++)
cin>>p[i].x>>p[i].y;
int cnt=0;
for(i=0;i<n;i++)
for(j=i+1;j<n;j++){
mid[cnt].x=p[i].x+p[j].x;
mid[cnt++].y=p[i].y+p[j].y;
}
init_hash();
for(i=0;i<cnt;i++)
ans+=insert(i);
cout<<ans<<endl;
}
return 0;
}
#include<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<cstdio>
const long long maxsize = 0x1fffff;
const int maxn = 1010;
using namespace std;
struct Point{
int x,y;
}p[maxn],mid[maxn*maxn];
int head[maxsize],next[maxn*maxn],res[maxn*maxn];
void init(){
memset(res,0,sizeof(res));
memset(head,-1,sizeof(head));
}
int get_hash(Point p){
return (((p.x<<2)+p.x>>4)^(p.y<<10))&maxsize;//传说这叫折叠法构造hash函数。。。
}
int insert(int i){
int h=get_hash(mid[i]);
//cout<<h<<endl;
int u=head[h];
while(u!=-1){
if(mid[u].x==mid[i].x&&mid[u].y==mid[i].y){
return res[u]++;
}
u=next[u];
}
next[i]=head[h];
head[h]=i;
res[i]=1;
return 0;
}
int main()
{
int t;
cin>>t;
while(t--){
int n,i,ans=0,j;
cin>>n;
for(i=0;i<n;i++)
cin>>p[i].x>>p[i].y;
int cnt=0;
for(i=0;i<n;i++)
for(j=i+1;j<n;j++){
mid[cnt].x=p[i].x+p[j].x;
mid[cnt++].y=p[i].y+p[j].y;
}
init();
for(i=0;i<cnt;i++)
ans+=insert(i);
cout<<ans<<endl;
}
return 0;
}

本文介绍了一种利用哈希表优化点对点配对计数的问题解决方法,通过两次迭代点集并使用哈希函数将每一对点的和映射到哈希表中,实现了对重复配对的有效计数。
459

被折叠的 条评论
为什么被折叠?



