POJ 2002 Squares 解题报告(哈希 开放寻址 & 链式)
经典好题。
题意是要我们找出所有的正方形。1000点,只有枚举咯。
如图,如果我们知道了正方形A,B的坐标,便可以推测出C,D两点的坐标。反之,遍历所有点作为A,B点,看C,D点是否存在。存在的话正方形数+1。
假设A点坐标为(x1,y1),B点坐标为(x2,y2),则根据三角形全等,易知
C点坐标:( x1+(y2-y1),y1-(x2-x1) )
D点坐标:( x2+(y2-y1),y2-(x2-x1) )
当然,如果我们遍历任意两个点,一个正方形将会被计数四次(四条边)。我们可以只判断斜率>=0的边,这条边在正方形的上方(如图AB边),这样不用重复验证四次了。
过程搞清楚了,下面要解决的就是如何判断C,D点是否存在了。
最简单的办法,直接使用set。我们把出现的点加到set里,判断时用find函数即可。当然,时效比较差。笔者测试是1000MS+。
而后,我们也可以使用二分查找。
当然,最快还是hash了。hash分为两种,开放寻址和链式,来解决冲突。在网上搜了很多解题报告,发现大家很多把链式叫做开放寻址……百度百科上有说明,大家可以看一下:http://baike.baidu.com/view/3140124.htm
下面,贴代码:
开放寻址,POJ测试最快是219MS,125MS级别的代码不知是如何实现的==
#include <cstdio>
#include <cstring> int prime[]={,,,,,,,}; int x[],y[];
int savex[],savey[];
bool hash[]; inline int calHash(int x,int y)
{
return ((x<<)^y)&;
} void insert(int x,int y)
{
int h=calHash(x,y);
int add=prime[(x^y)&];
while(hash[h] && (savex[h]!=x || savey[h]!=y))
{
h+=add;
h&=;
}
hash[h]=true;
savex[h]=x;
savey[h]=y;
} bool find(int x,int y)
{
int h=calHash(x,y);
int add=prime[(x^y)&];
while(hash[h] && (savex[h]!=x || savey[h]!=y))
{
h+=add;
h&=;
}
if(hash[h] && savex[h]==x && savey[h]==y)
return true;
return false;
} bool calK(int a,int b)
{
if(x[a]==x[b])
return false;
if(y[a]==y[b])
return true;
if(((x[a]-x[b])&(<<))==((y[a]-y[b])&(<<)))
return true;
return false;
} inline int Abs(int n)
{
return n<?-n:n;
} int main()
{
// freopen("in.txt","r",stdin);
int n;
while(~scanf("%d",&n) && n)
{
memset(hash,,sizeof(hash));
for(int i=;i<n;i++)
{
scanf("%d%d",x+i,y+i);
insert(x[i],y[i]);
} int count=;
for(int i=;i<n;i++)
for(int k=i+;k<n;k++)
{
if(calK(i,k))
{
int _y=Abs(y[i]-y[k]);
int _x=Abs(x[i]-x[k]);
if(find(x[i]+_y,y[i]-_x) &&
find(x[k]+_y,y[k]-_x))
count++;
}
}
printf("%d\n",count);
}
}
链式,即发现冲突就在当前位置加一个槽。POJ上最快319MS。当然,每次新建的槽并没有delete,会造成内存泄露,现实中还是别这么干,或者及时delete吧。
#include <cstdio>
#include <cstring> struct Point
{
int x,y;
bool operator<(const Point& cmp) const
{
return x==cmp.x?y<cmp.y:x<cmp.x;
}
} point[],p,q; struct Hash
{
int x,y;
Hash* next;
Hash()
{
next=;
}
} hash[]; inline int calHash(int x,int y)
{
return ((x<<)^y)&;
} void insert(int x,int y)
{
int h=calHash(x,y);
Hash* p=&hash[h];
while(p->next)
p=p->next;
p->x=x;
p->y=y;
p->next=new Hash();
} bool find(int x,int y)
{
int h=calHash(x,y);
Hash* p=&hash[h];
while(p->next)
{
if(p->x==x && p->y==y)
return true;
p=p->next;
}
return false;
} bool calK(Point& a,Point& b)
{
if(a.x==b.x)
return false;
if(a.y==b.y)
return true;
if(((a.x-b.x)&(<<))==((a.y-b.y)&(<<)))
return true;
return false;
} inline int Abs(int n)
{
return n<?-n:n;
} int main()
{
// freopen("in.txt","r",stdin);
int n;
while(~scanf("%d",&n) && n)
{
memset(hash,,sizeof(hash));
for(int i=;i<n;i++)
{
scanf("%d%d",&point[i].x,&point[i].y);
insert(point[i].x,point[i].y);
} int count=;
for(int i=;i<n;i++)
for(int k=i+;k<n;k++)
{
if(calK(point[i],point[k]))
{
int _y=Abs(point[i].y-point[k].y);
int _x=Abs(point[i].x-point[k].x);
if(find(point[i].x+_y,point[i].y-_x) &&
find(point[k].x+_y,point[k].y-_x))
count++;
}
}
printf("%d\n",count);
}
}
最简单的办法,set……1360MS
#include <cstdio>
#include <cstring>
#include <set>
using namespace std; struct Point
{
int x,y;
bool operator<(const Point& cmp) const
{
return x==cmp.x?y<cmp.y:x<cmp.x;
}
} point[],p,q; set<Point> ss; bool calK(Point& a,Point& b)
{
if(a.x==b.x)
return false;
if(a.y==b.y)
return true;
if(((a.x-b.x)&(<<))==((a.y-b.y)&(<<)))
return true;
return false;
} inline int Abs(int n)
{
return n<?-n:n;
} int main()
{
// freopen("in.txt","r",stdin);
int n;
while(~scanf("%d",&n) && n)
{
ss.clear();
for(int i=;i<n;i++)
{
scanf("%d%d",&point[i].x,&point[i].y);
ss.insert(point[i]);
} int count=;
for(int i=;i<n;i++)
for(int k=i+;k<n;k++)
{
if(calK(point[i],point[k]))
{
int _y=Abs(point[i].y-point[k].y);
int _x=Abs(point[i].x-point[k].x);
p.x=point[i].x+_y;
p.y=point[i].y-_x;
if(ss.find(p)==ss.end())
continue; p.x=point[k].x+_y;
p.y=point[k].y-_x;
if(ss.find(p)!=ss.end())
count++;
}
}
printf("%d\n",count);
}
}
三个版本是慢慢优化出来的,哈希函数也有区别。
POJ 2002 Squares 解题报告(哈希 开放寻址 & 链式)的更多相关文章
- poj 2002 Squares 几何二分 || 哈希
Squares Time Limit: 3500MS Memory Limit: 65536K Total Submissions: 15137 Accepted: 5749 Descript ...
- USACO Section1.2 Palindromic Squares 解题报告
palsquare解题报告 —— icedream61 博客园(转载请注明出处)------------------------------------------------------------ ...
- POJ 2002 Squares【值得摸索的一道二分+点旋转】
id=2002">Squares 很好的一道二分,事实上本来我是没有思路的,看了基神的题解之后才似乎明确了点. 题意:给出最多有1000个点,问这些点能够组成多少个正方形 分析:先想想 ...
- java哈希表(线性探测哈希表。链式哈希表)
哈希表(散列表) 通过哈希函数使元素的存储位置与它 的关键码之间能够建立一一映射的关系,在查找时可以很快找到该元素. 哈希表hash table(key,value) 的做法其实很简单,就是把Key通 ...
- POJ 2002 Squares 哈希
题目链接: http://poj.org/problem?id=2002 #include <stdio.h> #include <string.h> ; struct Has ...
- POJ 1840 Eps 解题报告(哈希)
a1x13+ a2x23+ a3x33+ a4x43+ a5x53=0,xi∈[-50,50],且xi!=0.让我们求所有解的可能. 首先,如果暴力判断的话,每个x的取值有100种可能,100^5肯定 ...
- 【原创】poj ----- 1182 食物链 解题报告
题目地址: http://poj.org/problem?id=1182 题目内容: 食物链 Time Limit: 1000MS Memory Limit: 10000K Total Submi ...
- POJ 2002 Squares 几何, 水题 难度: 0
题目 http://poj.org/problem?id=2002 题意 已知平面内有1000个点,所有点的坐标量级小于20000,求这些点能组成多少个不同的正方形. 思路 如图,将坐标按照升序排列后 ...
- poj 1201 Intervals 解题报告
Intervals Time Limit: 2000MS Memory Limit: 65536KB 64bit IO Format: %lld & %llu Submit Statu ...
随机推荐
- Wix: Using Patch Creation Properties - Minor Update
Based on the project created in Wix: Using Patch Creation Properties - Small Update, Following chang ...
- HDOJ 1176 免费馅饼 -- 动态规划
题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=1176 Problem Description 都说天上不会掉馅饼,但有一天gameboy正走在回家的小 ...
- HTMLImageElement类型的简便利用
这个是我在复习书籍的时候看见的,当时一个同学想通过页面发送请求,但是数据量不是太大,所以用的get方式,但是页面用表单提交请求的话会让页面进行跳转,当时我在网上查了一点资料,发现基本上都是通过ajax ...
- 转载:mysql 对于百万 千万级数据的分表实现方法
一般来说,当我们的数据库的数据超过了100w记录的时候就应该考虑分表或者分区了,这次我来详细说说分表的一些方法.目前我所知道的方法都是MYISAM的,INNODB如何做分表并且保留事务和外键,我还不是 ...
- AngularJS(4)-服务(Service)
1.$location服务 $location 服务,它可以返回当前页面的 URL 地址 2.$http服务 $http 是 AngularJS 应用中最常用的服务. 服务向服务器发送请求,应用响应服 ...
- lispbox 安装运行.sh的时候出现 lispbox.sh: 2: lispbox.sh: Bad substitution
安装lispbox时使用tar命令将压缩文件解压之后cd进入之后在运行.sh文件时出现了如下情况. $ sh lispbox.sh lispbox.: lispbox.sh: Bad substitu ...
- 查找计算机IP及占用端口
1. 在电脑启动搜索框,输入cmd回车打开命令提示符窗口. 输入ipconfig,就可以查看电脑的子网淹没,默认网关,IP等信息. 2. 查看本机开放的端口,即已被占用的端口号. 命令: netsta ...
- POJ1182并查集
食物链 时间限制:1000 ms | 内存限制:65535 KB 难度:5 描述 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物, ...
- 机器学习实战:数据预处理之独热编码(One-Hot Encoding)
问题由来 在很多机器学习任务中,特征并不总是连续值,而有可能是分类值. 例如,考虑一下的三个特征: ["male", "female"] ["from ...
- python 生成排列、组合以及选择
from <python cookbook> 19.15 任务 需要对一个序列的排列(permutation).组合(combination)或选择(selection)进行迭代操作.即使 ...