您的位置:首页 > 其它

POJ 2002 hash(枚举+哈希) 或者 枚举+二分

2009-10-06 20:33 513 查看
(zz)简单hash,具体做法是枚举任意两个点,因为有这由两个点所构成的边属于某个正方形那么可以计算出属于该正方形的另外两个点。如有两个点(a1,a2)和(b1,b2),那么如果点(a1+(a2-b2), a2-(a1-b1))和点(b1+(a2-b2), b2-(a1-b1))都存在则这四个点可以构成一个正方形。同时如果点(a1-(a2-b2), a2+(a1-b1))和点(b1-(a2-b2), b2+(a1-b1))存在那么点(a1,a2),(b1,b2),(a1-(a2-b2), a2+(a1-b1))和(b1-(a2-b2), b2+(a1-b1))又可以构成一个正方形,差不多思想就是这个样子,不过好像时间比较长1500多ms,应该还可以优化。
下面是AC代码:
#include<iostream>
using namespace std;
struct point
{
point()
{
index=-1;
next=NULL;
}
point(int index,point* next)
{
this->index=index;
this->next=next;
}
int index;
point* next;
};
int a[1001][2];
bool find(point hash_table[],int,int);
int main()
{
int n,value;
while(scanf("%d",&n)&&n)
{
long result=0;
point hash_table[40001];
for(int e=0;e<n;e++)
{
scanf("%d%d",&a[e][0],&a[e][1]);
value=a[e][0]+a[e][1];
if(value<0)value=-value;
if(hash_table[value].index==-1)hash_table[value].index=e;
else
{
point* p=&hash_table[value];
while(p->next!=NULL)p=p->next;
p->next=new point(e,NULL);
}
}
for(int x=0;x<n;x++)
for(int y=x+1;y<n;y++)
{
int d_x=a[x][0]-a[y][0];
int d_y=a[x][1]-a[y][1];
if(find(hash_table,a[x][0]-d_y,a[x][1]+d_x)&&
find(hash_table,a[y][0]-d_y,a[y][1]+d_x))
result++;
if(find(hash_table,a[x][0]+d_y,a[x][1]-d_x)&&
find(hash_table,a[y][0]+d_y,a[y][1]-d_x))
result++;
}
printf("%ld/n",result/4);
}
return 0;
}
bool find(point hash_table[40001],int x,int y)
{
int value=(x+y)<0?-(x+y):(x+y);
point* p=&hash_table[value];
if(p->index==-1)return false;
while(p!=NULL)
{
if(a[p->index][0]==x&&a[p->index][1]==y)return true;
p=p->next;
}
return false;
}
自己WA代码:
枚举+二分代码
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cmath>
using namespace std;
struct Point
{
int x;
int y;
bool operator==(const Point & p)
{
return x==p.x && y==p.y;
}
bool operator<(const Point & p)
{
return x<p.x ||( x==p.x && y<p.y);
}
}p[1005];
int num=0;
int cmp(const void * t1,const void *t2)
{
Point *p1 = (Point *)t1;
Point *p2 = (Point*)t2;
return *p2<*p1;
}
bool bin_search(Point *p,int s,int e,Point k)
{
int m;
int l,h;
l = s;
h=e;
while(l<=h)
{
m = l+(h-l)/2;
if(k==p[m])
{
return true;
}
else if(k<p[m])
{
h=m-1;
}
else
l=m+1;
}
return false;
}
void enumerate(int n)
{
int i ,j;
for(i=0;i<n;i++)
for(j=i+1;j<n;j++)//从最左边开始选边,然后枚举后面所有可能和当前边构成正方形的边
{
int x1 = p[i].x;
int y1 = p[i].y;
int x2 = p[j].x;
int y2 = p[j].y;
if(y1==y2)
continue;
Point t3,t4;
int tmp = abs(y1-y2);
t3.x= x1+tmp;
t4.x=x2 + tmp;
if(y1>y2)
{
t3.y = y1+(x2-x1);
t4.y = y2+(x2-x1);//
}
else if(y1 <y2)
{
t3.y = y1-(x2-x1);
t4.y = y2-(x2-x1);//
}
if(bin_search(p,j+1,n-1,t3)==true && bin_search(p,j+1,n-1,t4)==true)
num++;
}
}
int main()
{
int n ;
int i = 0;
cin>>n;
while(n!=0)
{
num=0;
memset(p,0,sizeof(p));
for(i=0;i<n;i++)
{
cin>>p[i].x;
cin>>p[i].y;
p[i].x=p[i].x;
p[i].y=p[i].y;
}
qsort(p,n,sizeof(struct Point),cmp);
enumerate(n);//枚举
cout<<num<<endl;
cin>>n;
}
}

枚举+hash代码
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cmath>
using namespace std;
struct Point
{
int x;
int y;
bool operator==(const Point & p)
{
return x==p.x && y==p.y;
}
Point *next;
}p[1005];
Point *hash[20000];
const int P = 19977;
int num=0;
int cmp(const void * t1,const void *t2)
{
Point *p2 = (Point *)t1;
Point *p1 = (Point*)t2;
if(p1->x < p2->x)
return 1;
else if(p1->x == p2->x)
if(p1->y < p2->y)
return 1;
else
return -1;
return -1;
}
bool find(Point p)
{
int key = p.x+p.y;
Point *n = hash[key%P];
while(n)
{
if(*n==p)
return true;
n=n->next;
}
return false;
}
void insert(Point p)
{
int key = p.x+p.y;
Point * m = new Point;
m->x=p.x;
m->y=p.y;
m->next=hash[key%P];
hash[key%P]=m;
}
void solve(int n)
{
int i = 0;
int j = 0;
for(i=0;i<n;i++)
for(j=i+1;j<n;j++)//从最左边开始选边,然后枚举后面所有可能和当前边构成正方形的边
{
int x1 = p[i].x;
int y1 = p[i].y;
int x2 = p[j].x;
int y2 = p[j].y;
Point t3,t4;
t3.x= x1+(y1-y2);
t3.y = y1-(x1-x2);
t4.x = x2+(y1-y2);
t4.y= y2-(x1-x2);
if(find(t3) && find(t4))
num++;
t3.x= x1-(y1-y2);
t3.y = y1+(x1-x2);
t4.x = x2-(y1-y2);
t4.y= y2+(x1-x2);
if(find(t3) && find(t4))
num++;
}
}
int main()
{
int n ;
int i = 0;
cin>>n;
while(n!=0)
{
num=0;
memset(p,0,sizeof(p));
for(i=0;i<20000;i++)
{
hash[i]=NULL;
}
for(i=0;i<n;i++)
{
cin>>p[i].x;
cin>>p[i].y;
insert(p[i]);
}
qsort(p,n,sizeof(Point),cmp);
solve(n);
cout<<num/4<<endl;
cin>>n;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: