Hash poj2002 Squares

仿照之前的雪花,Hash函数随便搞个。

?





1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

#include <cstdio>

#include <cstdlib>

#include <cstring>

#include <algorithm>

#include <cmath>

#include <stack>

#include <queue>

#include <vector>

#include <map>

#include <string>

#include <iostream>

const
int INF = 9973;

const
int kk = 1007;

struct
Node

{

    int
x;int y; int
hash_val;

}node[INF][100];

int
Abs(int
x)

{

    return
x>0?x:-x;

}

int
get_hash(Node &a)

{

    a.hash_val= a.x*a.y+a.y*kk;

    return
a.hash_val = Abs(a.hash_val)%INF;

}

int
Hash(int
x,int y)

{

    return
Abs(x*y+y*kk)%INF;

}

int
len[INF];

void
Insert(Node a)

{

    int
val=get_hash(a);

    for(int
i=0;i<len[a.hash_val];i++)

        if(node[val][i].x==a.x&&node[val][i].y==a.y)

        return
;

    node[val][len[a.hash_val]++]=a;

}

int
match(int 
x,int y)

{

    int
hash1=Hash(x,y);

    for(int
i=0;i<len[hash1];i++)

        if(node[hash1][i].x==x&&node[hash1][i].y==y)

        return
1;

    return
0;

}

int
main()

{

    int
n;

    Node a[20000];

    while(scanf("%d",&n),n){

        memset(node,0,sizeof(node));

        memset(len,0,sizeof(len));

        for(int
i=0;i<n;i++){

            scanf("%d%d",&a[i].x,&a[i].y);

            int
val=get_hash(a[i]);

            Insert(a[i]);

        }

        int
ans=0;

        for(int
i=0;i<n;i++){

            for(int
j=i+1;j<n;j++){

                int
x1=a[i].x-a[i].y+a[j].y;int
y1=a[i].y-a[j].x+a[i].x;

                int
x2=a[j].x+a[j].y-a[i].y;int
y2=a[j].y-a[j].x+a[i].x;

                int
x3=a[i].x-a[j].y+a[i].y;int
y3=a[i].y-a[i].x+a[j].x;

                int
x4=a[j].x-a[j].y+a[i].y;int
y4=a[j].y+a[j].x-a[i].x;

                if(match(x1,y1)&&match(x2,y2))

                    ans++;

                if(match(x3,y3)&&match(x4,y4))

                    ans++;

            }

        }

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

    }

    return
0;

}

  

时间: 2024-11-05 19:45:08

Hash poj2002 Squares的相关文章

Poj2002 Squares

题意描述:有一堆平面散点集,任取四个点,求能组成正方形的不同组合方式有多少.相同的四个点,不同顺序构成的正方形视为同一正方形. 思路变迁: 1.最简单的方法,直接暴力搜索,即依次取四个顶点,根据其坐标判断是否能组成正方形.组成正方形的条件是四个顶点可组成的六条边里面,有四条相等,剩下两条相等.当然由于其时间复杂度为O(n^4),所以提交结果为TLE 2.考虑降低时间复杂度.如任取三个顶点,根据组成正方形的条件计算得到第四个顶点,判断其是否在点的集合内,其复杂度为O(n^3).或者任取两个顶点,根

[POJ2002]Squares(计算几何,二分)

题目链接:http://poj.org/problem?id=2002 给定一堆点,求这些点里哪些点可以构成正方形,题目给定n<=1000,直接枚举四个点是肯定会超时的,因此要做一些优化. 有公式,已知两个点在正方形对角,分别是(x1,y1)和(x2,y2),那么围成正方形后另外两个点(x3,y3)和(x4,y4)分别为: x3 = x2 - (x2 - y1) y3 = x2 + (x2 - x1) x4 = x1 - (x2 - y1) y4 = y1 + (x2 - x1) 那么我们需要枚

POJ2002 Squares(二维点哈希)

题目链接: http://poj.org/problem?id=2002 题意: 给定n个点 判断这n个点可以构成多少正方形. 分析: 暴力枚举一条边的两个端点,然后根据全等三角形可以求出可以构成正方形的另外两个边的端点,然后判断这两个两存不存在. 因此首先要把所有的点哈希一下,然后依次暴力枚举,因此四条边都统计了一次 因此最后要除4. 代码如下: #include <iostream> #include <cstdio> #include <algorithm> #i

POJ2002:Squares

Description 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 latte

poj 2002 Squares,hash

poj 2002 Squares 给出n个点,问能组成多少个正方形? 题解: 先把每个点hash 然后枚举两点(即枚举正方形的一条边),然后通过三角形全等,可以推出正方形的另外两点,在hash表里查找这两点看是存在,存在则 Cnt +1. 最后 answer = Cnt/4 //因为同一正方形都统计了4次. #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const

URAL 1486 Equal Squares 二维Hash

Hash在信息学竞赛中的一类应用 论文中的第一道例题,关于二维hash的一些处理方法和小技巧 通过RK法计算hash值如果不取模的话可以O(n)预处理,然后O(1)得到任意一个字串的hash值 得到任意子串的hash值的时候不能用除和取模运算了,显然是错的 二维hash如果使用RK法每一次的p值必须不一样 如果不能确定hash值一定不是唯一的,可以计算一个用来确定pos 的hash值和一个用来确定值的hash值 代码写的相当挫,不忍直视 #include <cstdio> #include &

POJ 2002 Squares 数学 + 必须hash

http://poj.org/problem?id=2002 只能说hash比二分快很多.随便一个hash函数都可以完爆二分. 判断是否存在正方形思路如下: 1.枚举任意两个点,作为正方形的一条边,那么,整个正方形就确定了,有两个方向. 因为, 设枚举的坐标为(x1, y1) & (x2, y2),所求的坐标是和x1,y1这个点相连,那么有方程如下. 1.垂直,向量积是0 2.边长相等,然后距离公式化简. 即可解出剩下的两个点. 然后要注意两个点要在正方形的同一侧,不然变了平行四边形了. 唤醒了

poj2002 hash+数学

1 .求不同的四个点组成最大正方形的总个数: 2.由(x1,y1),(x2,y2),可以求出另外两点的坐标: 即 x3=x1+(y1-y2);y3=y1-(x1-x2); x4=x2+(y1-y2);y4=y2-(x1-x2); 或者 x3=x1-(y1-y2);y3=y1+(x1-x2); x4=x2-(y1-y2);y4=y2+(x1-x2); 3.由求出的点的坐标可以hash查找是否存在,如果存在就加一: 4.最终答案为8倍的正方形个数: 5.源码: #include<iostream>

hdu1246 Counting Squares(暴力hash)

题目意思: 每行给出4个正整数,代表矩形的四个顶点坐标,现给出一系列的数据,当给的数-1 -1 -1 -1时表示一组数据结束,给出这些矩形覆盖的面积,当数据为-2 -2 -2 -2时结束输入. http://acm.hdu.edu.cn/showproblem.php?pid=1264 题目分析: 首先注意到数据范围较小,而且给的数据为正整数,但是不能重复计算面积,因此我们化整为零计算每个矩形分成的单位面积1的个数,进行累加即可,为了保证不重复计算面积,用一个二维数组表示该面积已经被计算即可,见