poj2002 排序+哈希
来源:互联网 发布:北京赛车pk10微信源码 编辑:程序博客网 时间:2024/06/17 01:24
/** * poj 2002 排序+哈希 * 首先要有一个正确的大方向,就是取两个点,利用公式给出另外两个点,并搜索这另外的两个点是否存在 * 大方向有了,首先是确定另外两个点的方法,随意取点,可能组出多个正方形,判断的时候会取多次,这就浪费了很多运算量 * 吸取了别人代码的经验,首先将点先x后y升序排列,然后对于i<j,只考虑yi>=yj的点。有所改进的是,我们这里不需要对xi==xj的情况多做判断,这是因为排序之后,不可能有xi==xj,yi>=yj的情况出现 * 这样,得到两点取另两点的方向就可以放在第一象限方向(正方向)了 * 下面是哈希,其实是就是哈希的原理,只是我是第一次手写哈希的构造和搜索,所以写出来很蹩脚。而且因为最开始,多轮运算之间忘了重新初始化HASH表,WA了好多次 * 既然是第一次写哈希,就把哈希的原理也说一下吧.简单地说,我们用数组索引指向数据,而搜索的时候是用数据查找索引,哈希就是另外构建了一张表,将数据通过函数计算出一个下标,将原数组的索引作为值,以链表的形式存起来 * 对于不可能出现哈希值重复的情况,就不需要使用链表,而像题目中这种情况,肯定会有重复的,就需要用链表来在重复的情况下进行查找。如何将整个数据范围尽量平摊到哈希表长度上,就是哈希函数选取的关键了 * 我这里是随便取的,找了一个素数7993,取((abs(x)+1)*(abs(y)+1))%7993作为哈希函数,还好,344ms就过了 * 这道题好像还有一种二分搜索的做法,我这里就不尝试了 */#include <cstdio>#include <iostream>#include <cstdlib>using namespace std;const int MAX_NUM = 1001;const int PRIME = 7993;struct point{ int x; int y;} p[MAX_NUM];struct node{ int index; node* next; node(){ index = -1; next = NULL; } node(int i){ index = i; next = NULL; }};int abs(int i){ return (i>=0) ? i : -1*i;}int cmp(const void* a,const void* b){ point *p1=(point*)a,*p2=(point*)b; if(p1->x != p2->x){ return p1->x - p2->x; } else{ return p1->y - p2->y; }}bool find(node* hash,int x,int y){ int key = ((abs(x)+1) * (abs(y)+1)) % PRIME; node *pn; if(hash[key].index < 0){ return false; } else{ pn = &hash[key]; while(pn != NULL){ if(p[pn->index].x == x && p[pn->index].y == y){ return true; } else{ pn = pn->next; } } return false; }}int main(){ int n,res; scanf("%d",&n); while(n!=0){ node hash[PRIME]; int key; node *pp; for(int i=0;i<n;++i){ scanf("%d%d",&p[i].x,&p[i].y); } qsort(p,n,sizeof(point),cmp); for(int i=0;i<n;++i){ //construct hash table key = ((abs(p[i].x)+1) * (abs(p[i].y)+1)) % PRIME; if(hash[key].index == -1){ hash[key].index = i; } else{ pp = &hash[key]; while(pp->next != NULL){ pp = pp->next; } pp->next = new node(i); } } res = 0; int x1,x2,y1,y2,x3,x4,y3,y4,ydiff,xdiff; for(int i=0;i<n;++i){ x1 = p[i].x; y1 = p[i].y; for(int j=i+1;j<n;++j){ if(p[j].y <= p[i].y){ x2 = p[j].x; y2 = p[j].y; ydiff = abs(y1-y2); xdiff = abs(x1-x2); x3 = x1 + ydiff; x4 = x2 + ydiff; y3 = y1 + xdiff; y4 = y2 + xdiff; if(find(hash,x3,y3) && find(hash,x4,y4)){ ++res; } } } } printf("%d\n",res); scanf("%d",&n); } return 0;}
0 0
- poj2002 排序+哈希
- poj2002 哈希
- POJ2002《Squares》方法:哈希
- POJ2002
- poj2002
- poj2002
- poj2002
- POJ2002
- poj2002
- poj2002 squares 哈希 计算几何
- POJ2002 Squares
- poj2002 hash
- poj2002 Squares
- poj2002 Squares
- POJ2002-Squares
- POJ2002:Squares
- Squares-POJ2002
- Squares-POJ2002
- 统计分布学习笔记(未完)
- poj1990 树状数组+排序
- poj2001 字典树
- 测试时钟显示程序通过, 点阵显示 碰到一些困难 发现调试比写代码更纠结。代码没错 烧到板子里就是打不到想要的现象
- 用PNG透明图片和GDI+做不规则透明窗体
- poj2002 排序+哈希
- poj 1742 多重背包算法优化问题
- poj2023 DFS
- UVa 10000 - Longest Paths
- poj2038 模拟+next_permutation
- java 软引用 弱引用 缓存
- poj2051 优先队列(自实现版本和STL版本)
- Label的创建方法
- HDU 1072 Nightmare