您的位置:首页 > 其它

POJ 1971 Parallelogram Counting(枚举+HASH)

2010-08-06 12:28 405 查看
//枚举 + HASH
//和2002很像,这次是找平行四边形,规模1000,因此只能采用O(N^2)
//一开始我是想到枚举3个点确定2条边,由这2条边确定第4的点,再用HASH判断是否存在,但是O(n^3)绝对TLE
//再想了一下,发现可以枚举对角线,进而确定中点,2条直线如果中点相同,那么必定确定一个平行四边形
//根据这个性质来对边的中点值进行HASH就可以了,发现一个中点值就插入,并计数,最后答案就是这些计数的总和
//效率的关键是HASH函数的设计,我用折叠法的HASH随便搞了一通,再随便确定一个MAXHASH,结果居然有766MS
//刷到第一版,哈哈!
#include<iostream>
using namespace std;
const int MAXHASH = 7345787;
int head[MAXHASH],next[1000003];
int m,ans;
struct coord
{
long x,y;
}P[1005];
struct midPoint
{
long x,y,cnt;//cnt计算出现的次数
}G[1000003];
int hash(int x,int y)//拿折叠法的HASH乱改了一下。。。
{
int h = 0;
h = ((x<<2) + (x>>4)) ^ (y<<10);
h = h % MAXHASH;
h = h < 0 ? h + MAXHASH : h;
return h;
}
void insert(int x,int y)
{
int h = hash(x,y);
bool Find = 0;
for(int e = head[h];e != -1;e = next[e])
{
if(G[e].x == x && G[e].y == y)
{
Find = 1;
ans += G[e].cnt++;
break;
}
}
if(!Find)
{
G[m].x = x;
G[m].y = y;
G[m].cnt = 1;
next[m] = head[h];
head[h] = m++;
}
}
int main()
{
//freopen("in.txt","r",stdin);
int t,n,x,y;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
memset(head,-1,sizeof(head));
memset(G,0,sizeof(G));
m = ans = 0;
for(int i = 0;i < n;++i)
scanf("%ld%ld",&P[i].x,&P[i].y);

for(int i = 0;i < n;++i)
for(int j = i + 1;j < n;++j)//枚举边
insert(P[i].x + P[j].x,P[i].y + P[j].y);

printf("%d/n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: