POJ2002_Squares (哈希表)

本文出自:blog.csdn.net/svitter

题意


  • A square is a 4-sided polygon whose sides have equal length and adjacent sides form 90-degree angles. It is also a polygon such that rotating about its centre by 90 degrees gives the same polygon. It is not the only polygon with the latter property, however,
    as a regular octagon also has this property.

    So we all know what a square looks like, but can we find all possible squares that can be formed from a set of stars in a night sky? To make the problem easier, we will assume that the night sky is a 2-dimensional plane, and each star is specified by its
    x and y coordinates.

  • 一共可以在给出的n个点中找出多少个正方形?

输入输出分析


  • The input consists of a number of test cases. Each test case starts with the integer n (1 <= n <= 1000) indicating the number of points to follow.

    Each of the next n lines specify the x and y coordinates (two integers) of each point.

    You may assume that the points are distinct and the magnitudes of the coordinates are less than 20000. The input is terminated when n = 0.

  • 有多组测试数据,每一个测试数据n开始,n <1000说明最多有1000个点。坐标系的横纵坐标不会超过20000, 以n=0结束

算法数据结构分析



本题目用哈希表+简单的分析做~

  • 给出4个点,如果四重循环N**4必然超时,那么枚举两个点来计算出对应的两个点,计算对应点是否存在

  • 计算方法见getPoint()函数
  • 计算定应点是否存在的最快速度就是使用hash来查找。把(x+y)mod m,即取余法。最多有1000个点,所以哈希表1000个slot足够。

    保险起见,开1010,M取质数1009。

  • 使用拉链法解决冲突,开一个next数组,来保存下标i对应到hash表上,因为最多1000个节点,最糟糕的情况下需要999个卫星表, 所以next数组开·1010即可。

AC代码:

//author: svtter
//

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <vector>
#include <map>
#include <algorithm>
#include <queue>
#include <cmath>

#define INF 0xffffff
#define lln long long

#ifdef ONLINE_JUDGE
#define FOI(file) 0
#define FOW(file) 0
#else
#define FOI(file) freopen(file,"r",stdin);
#define FOW(file) freopen(file,"w",stdout);
#endif

using namespace std;

#define MAXN 1010
#define MOD 1009
struct node
{
    int x, y;
    bool operator == (const node &a)const
    {
        return (x == a.x && y == a.y);
    }
    bool operator < (const node &a)const
    {
        if(x!=a.x)
            return x <a.x;
        return y < a.y;
    }
};
node point[MAXN];
int hash[MAXN+1], next[MAXN];

int n;

node c, d;
void getPoint(node &a, node &b)
{
    c.x = b.x + (b.y - a.y);
    c.y = b.y - (b.x - a.x);
    d.x = a.x + (b.y - a.y);
    d.y = a.y - (b.x -a.x);
}

int getHash(node &a)
{
    return abs(a.x+ a.y) % MOD;
}

void insertHash(int i)
{
    //头插入,拉链法
    int key = getHash(point[i]);
    next[i] = hash[key];
    hash[key] = i;
}

bool search(node &t)
{
    int key = getHash(t);
    int i = hash[key];
    while(i != -1)
    {
        if(point[i] == t)
            return true;
        i = next[i];
    }
    return false;
}

int main()
{
    FOI("input");
    //FOW(output);

    int i, j;
    int ans;
    //write your programme here
    while(~scanf("%d", &n))
    {
        if(n == 0)
            break;
        memset(hash , -1 ,sizeof(hash));
        memset(next , -1, sizeof(next));
        for(i = 0; i < n; i++)
            scanf("%d%d", &point[i].x, &point[i].y);
        sort(point ,point+n);
        //puts("input over.");

        for(i = 0; i < n; i++)
            insertHash(i);
        //puts("build hash over.");

        ans = 0;
        for(i = 0; i < n; i++)
        {
            for(j = i+1; j < n; j++)
            {
                getPoint(point[i], point[j]);
                if(search(c) && search(d))
                    ans++;
            }
        }

        printf("%d\n", ans/2);
    }

    return 0;
}

时间: 2024-10-28 07:01:13

POJ2002_Squares (哈希表)的相关文章

哈希表

哈希表支持的一种最有效的检索方法:散列. 由于计算哈希值和在数组中进行索引都只消耗固定时间,因此哈希表的最大亮点在于他是一种运行时间在常量级的检索方法. 哈希表主要有两种: 1.链式哈希表:将数据存储在桶中的哈希表,每个桶里面都是一个链表,且链表的容量随着冲突的增大而增大.(换句话说就是如果有冲突,会在桶中的链表加上一个存储的值) 2.开地址哈希表:将数据存在表本身,而不是在桶中,他通过各种探查方法来避免冲突. 解决冲突: 不管在以上那种哈希表中,我们的目标是尽可能均匀的分配表中的元素.所以我们

8. 蛤蟆的数据结构进阶八哈希表相关概念

8. 蛤蟆的数据结构进阶八哈希表相关概念 本篇名言:"作家当然必须挣钱才能生活,写作,但是他决不应该为了挣钱而生活,写作.--马克思" 前些笔记我们学习了二叉树相关.现在我们来看下哈希表.这篇先来看下哈希表的相关概念 欢迎转载,转载请标明出处:http://blog.csdn.net/notbaron/article/details/47347273 1.  哈希表的概念 哈希表(HashTable)也叫散列表,是根据关键码值(Key Value)而直接进行访问的数据结构.它通过把关键

哈希表——线性探测法、链地址法、查找成功、查找不成功的平均长度

一.哈希表 1.概念 哈希表(Hash Table)也叫散列表,是根据关键码值(Key Value)而直接进行访问的数据结构.它通过把关键码值映射到哈希表中的一个位置来访问记录,以加快查找的速度.这个映射函数就做散列函数,存放记录的数组叫做散列表. 2.散列存储的基本思路 以数据中每个元素的关键字K为自变量,通过散列函数H(k)计算出函数值,以该函数值作为一块连续存储空间的的单元地址,将该元素存储到函数值对应的单元中. 3.哈希表查找的时间复杂度 哈希表存储的是键值对,其查找的时间复杂度与元素数

【搜索引擎(二)】索引、倒排索引、哈希表、跳表

索引 其实在计算机中我们早已接触过跟索引有关的东西,比如数据库里的索引(index),还有硬盘文件系统中其实也有类似的东西,简而言之,索引是一种为了方便找到自己需要的东西而设计出来的条目,你可以通过找索引找到自己想要内容的位置.索引过程是: 关键字->索引->文档.在图书馆内的书分门别类,就是一种按类别来分的索引.当然索引还有很多其他的实现. 仅仅有索引的概念是不够的.虽然分门别类是一种方法,但是我们在拥有一堆文档的时候必须要有从文档到索引的规范过程,并且索引的结构要满足能够让人(或者计算机)

哈希表的简单操作

哈希表中,关键值通过哈希函数映射到数组上,查找时通过关键值直接访问数组.哈希表的关键问题在于哈希函数的构造和解决冲突的方法. 下面采用最简单的线性探测展示一下哈希表的基本操作: 1 //Hashtable 2 class HashTable { 3 private: 4 string *elem; 5 int size; 6 public: 7 HashTable() { 8 size = 2000; 9 elem = new string[size]; 10 for (int i = 0; i

Stack集合 Queue队列集合 Hashtable哈希表

Stack集合 干草堆集合 栈集合 栈;stack,先进后出,一个一个赋值,一个一个取值,安装顺序来. 属性和方法 实例化 初始化 Stack st = new Stack(); 添加元素 1 个数 2 Console.WriteLine(st.Count); 3 只要使用一次pop方法,就会从最后一个元素开始排除 弹出 4 Console.WriteLine(st.Pop()); 5 Console.WriteLine(st.Count); 6 只想查看不弹出 7 Console.WriteL

深入理解哈希表

有两个字典,分别存有 100 条数据和 10000 条数据,如果用一个不存在的 key 去查找数据,在哪个字典中速度更快? 有些计算机常识的读者都会立刻回答: “一样快,底层都用了哈希表,查找的时间复杂度为 O(1)”.然而实际情况真的是这样么? 答案是否定的,存在少部分情况两者速度不一致,本文首先对哈希表做一个简短的总结,然后思考 Java 和 Redis 中对哈希表的实现,最后再得出结论,如果对某个话题已经很熟悉,可以直接跳到文章末尾的对比和总结部分. 哈希表概述 Objective-C 中

哈希表(开链法)

纯代码 #pragma once #include <iostream> #include <vector> using namespace std; struct __HashFuncString { size_t operator()(const string &key) { size_t hash = 0; for (size_t i = 0; i < key.size(); ++i) { hash += key[i]; } return hash; } };

哈希表/散列表

哈希表/散列表,是根据关键字(key)直接访问在内存存储位置的数据结构. 构造哈希表的常用方法: 直接地址法---取关键字的某个线性函数为散列地址,Hash(Key) = Key或Hash(key) = A*Key + B, A,B为常数. 除留余数法---取关键值被某个不大于散列表长m的数p除后的所得的余数为散列地址. Hash(key) = key % p. 若采用直接地址法(Hash(Key) = Key)存在一定的缺陷. 当Key值特别大时,而Key之前的数很少,就会造成空间浪费.大多时