POJ2002 二分查找&哈希

问题重述:

给定整数n,以及n个点的坐标xi, yi。求这n个点可以组成的正方形的数目(每个点可重复使用)。

分析:

根据正方形的性质,给定两个点就能确定可能构成的两个正方形的另外两个顶点。因此,只需要遍历所有点中的两个顶点,计算出可构成正方形的另外两个顶点的坐标,再在已知点中查找这两个点是否存在即可算出正方形数目。

AC代码:

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 #include <algorithm>
 5
 6 using namespace std;
 7
 8 const int maxn = 1010;
 9 int n;
10
11 struct node
12 {
13     int x, y;
14     bool operator <  (const node n) const {
15         if ( x != n.x )
16             return x < n.x;
17         else
18             return y < n.y;
19     }
20 }star[maxn];
21
22 bool search(int x, int y)
23 {
24     int low = 0;
25     int high = n;
26     while (low <= high) {
27         int mid = (low + high) / 2;
28         if (star[mid].x == x && star[mid].y == y)
29             return true;
30         else {
31             if (x < star[mid].x || (x == star[mid].x && y < star[mid].y ))
32                 high = mid - 1;
33             else
34                 low = mid + 1;
35         }
36     }
37     return false;
38 }
39
40 node s1, s2, s3, s4;
41
42 void compute(int a, int b)
43 {
44     int xa = star[a].x;
45     int xb = star[b].x;
46     int ya = star[a].y;
47     int yb = star[b].y;
48     s1.x = xa - yb + ya;
49     s1.y = ya + xb - xa;
50     s2.x = xb - yb + ya;
51     s2.y = yb + xb - xa;
52
53     s3.x = xa + yb - ya;
54     s3.y = ya - xb + xa;
55     s4.x = xb + yb - ya;
56     s4.y = yb - xb + xa;
57 }
58
59 int main()
60 {
61     while (scanf("%d", &n) && n) {
62         for (int i = 0; i < n; i++) {
63             scanf("%d%d", &star[i].x, &star[i].y);
64         }
65         sort(star, star + n);
66         int ans = 0;
67         for (int i = 0; i < n; i++)
68             for (int j = i + 1; j < n; j++) {
69                 compute(i, j);
70                 if (search(s1.x, s1.y) && search(s2.x, s2.y))
71                     ans++;
72                 if (search(s3.x, s3.y) && search(s4.x, s4.y))
73                     ans++;
74             }
75         ans /= 4;
76         printf("%d\n", ans);
77     }
78     return 0;
79 }

此代码对于所有的点进行二分查找以确定指定点是否存在,因此效率并不高。假如用h[i]存储横坐标为i的点的纵坐标,在通过在h[i]中二分查找指定点是否存在,应该能够大幅提升效率。

POJ2002 二分查找&哈希

时间: 2024-10-21 03:10:26

POJ2002 二分查找&哈希的相关文章

[LeetCode] #1# Two Sum : 数组/哈希表/二分查找

一. 题目 1. Two SumTotal Accepted: 241484 Total Submissions: 1005339 Difficulty: Easy Given an array of integers, return indices of the two numbers such that they add up to a specific target. You may assume that each input would have exactly one solutio

2. C#数据结构与算法 -- 查找算法(顺序查找,哈希查找,二分查找(折半),索引,二叉)

1. 顺序查找算法 ===================================================== 算法思想简单描述: 最突出的查找类型就是从记录集的开始处顺次遍历每条记录,直到找到所要的记录或者是 到达数据集的末尾.这就是所谓的顺序查找.顺序查找(也被称为线性查找)是非常容易实现 的.从数组的起始处开始,把每个访问到的数组元素依次和所要查找的数值进行比较.如果找 到匹配的数据项,就结束查找操作.如果遍历到数组的末尾仍没有产生匹配,那么就说明此数 值不在数组内. ==

偏移二分查找

偏移二分查找 系列: 活着,就一直在忙碌,从未有停歇. 今天主要分享一下偏移二分查找算法,至于常用的顺序查找.二分查找.哈希查找.堆查找等,这里就不多说了. 思路:如果数据项规则变化,可先偏移到一个较小区间再用二分查找. 场景:股票的行情日期,末尾数字规则的整数序列等. 举一个例子,如个位数不为3.6.9的三位自然数序列,查找725. 先计算可能的位置x,再根据该位置数据项和要查找的数据项的值的差异,计算索引偏移量,在可能的索引区间中二分查找即可,可以提升二分查找算法的效率,来比较一下: 看起来

查找算法总结(二分查找/二叉查找树/红黑树/散列表)

1.二分查找 二分查找时,先将被查找的键和子数组的中间键比较.如果被查找的键小于中间键,就在左子数组继续查找,如果大于中间键,就在右子数组中查找,否则中间键就是要找的元素. /** * 二分查找 */ public class BinarySearch { public static int find(int[] array, int key) { int left = 0; int right = array.length - 1; // while (left <= right)不能改为<

查找算法系列之简单查找:顺序查找、二分查找、分块查找

近期总结了各大排序算法的原理 ,并对其进行了实现,想着一并把查找算法总结了,今天就着手开始总结查找算法. 废话不多说,这篇文章从最简单的查找算法开始讲起,之后会补充复杂的二叉搜索树查找(BST)和B树,B+树查找以及哈希查找等. 顾名思义,查找就是寻找到关键字在队列中的位置,最笨的查找算法就是依次顺序比较,复杂度为O(n),但是有很多方法的复杂度可以达到O(logn)等等. 1.顺序查找 关键字与数组中的数顺序比较,时间复杂度O(n). template<class T> int OrderS

列表查找及二分查找

1. 查找算法 描述顺序查找与二分法(折半搜索)的概念以及用python实现其查找流程 一.顺序查找 1. 什么是顺序查找 当数据存储在诸如列表的集合中时,我们说这些数据具有线性或顺序关系. 每个数据元素都存储在相对于其他数据元素的位置. 由于这些索引值是有序的,我们可以按顺序访问它们. 这个过程产实现的搜索即为顺序查找. 2. 顺序查找原理剖析: 从列表中的第一个元素开始,我们按照基本的顺序排序,简单地从一个元素移动到另一个元素,直到找到我们正在寻找的元素或遍历完整个列表.如果我们遍历完整个列

二分查找

递归版(在区间[x, y)中找v的位置) 1 //递归版二分查找 2 int bsearch(int * A, int x, int y, int v) 3 { 4 5 if(v<a[x] || v>a[y-1]) return -1; 6 int m = x + (y-x)/2; //此处能不能用int m = (x+y)/2,需要仔细考虑(暂时想不到原因) 7 if(A[m]==v) return m; 8 else if(A[m]>v) return bsearch(A, x, m

二分查找总结

最近刷leetcode和lintcode,做到二分查找的部分,发现其实这种类型的题目很有规律,题目大致的分为以下几类: 1.最基础的二分查找题目,在一个有序的数组当中查找某个数,如果找到,则返回这个数在数组中的下标,如果没有找到就返回-1或者是它将会被按顺序插入的位置.这种题目继续进阶一下就是在有序数组中查找元素的上下限.继续做可以求两个区间的交集. 2.旋转数组问题,就是将一个有序数组进行旋转,然后在数组中查找某个值,其中分为数组中有重复元素和没有重复元素两种情况. 3.在杨氏矩阵中利用二分查

二分查找JAVA实现

二分查找又称折半查找,优点是比较次数少,查找速度快,平均性能好:其缺点是要求待查表为有序表,且插入删除困难.因此,折半查找方法适用于不经常变动而查找频繁的有序列表.首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功:否则利用中间位置记录将表分成前.后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表.重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功. 一.概念 二分查