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>
#include<stdio.h>
using namespace std;
const int prime=99991;
struct Node
{
    int x;
    Node *next;
};
Node hash[100000];
int a[20000],b[20000];
int n;
void insert(int key,int i)
{
    if(hash[key].x==0)
    {
        hash[key].x=i;
    }
    else{
        Node *p=&hash[key],*pp;
        while (p!=NULL)
        {
            pp=p;
            p=p->next;
        }
        Node *p1 = new Node;
        p1->x=i;
        p1->next=NULL;
        pp->next=p1;
    }
}
void init()
{
    int i,j;
    for (i=0;i<=99991;i++) {hash[i].x=0;hash[i].next=NULL;}
    for (i=1;i<=n;i++)
    {
        scanf("%d%d",&a[i],&b[i]);
        int key=(a[i]*a[i]+b[i]*b[i])%prime;
        insert(key,i);
    }
}
int ans;
bool find(int key,int x,int y)
{
    Node *p=&hash[key];
    while (p!=NULL)
    {
        if(a[p->x]==x&&b[p->x]==y) return true;
        p=p->next;
    }
    return false;
}
void make()
{
    ans=0;
    int key1,key2,x1,x2,y1,y2;
    int i,j;
    for (i=1;i<=n;i++)
        for (j=1;j<=n;j++)
     if(i!=j)          {
              x1=a[i]+b[i]-b[j];y1=b[i]-(a[i]-a[j]);
              x2=a[j]+b[i]-b[j];y2=b[j]-(a[i]-a[j]);
              key1=(x1*x1+y1*y1)%prime;
              key2=(x2*x2+y2*y2)%prime;
              if(find(key1,x1,y1)&&find(key2,x2,y2)) ans++;//cout<<x1<<"  "<<y1<<endl;cout<<x2<<" "<<y2<<endl;}
              x1=a[i]-(b[i]-b[j]);y1=b[i]+(a[i]-a[j]);
              x2=a[j]-(b[i]-b[j]);y2=b[j]+(a[i]-a[j]);
               key1=(x1*x1+y1*y1)%prime;
              key2=(x2*x2+y2*y2)%prime;
              if(find(key1,x1,y1)&&find(key2,x2,y2)) ans++;
          }
    printf("%d\n",ans/8);
}
int main()
{
    while(scanf("%d",&n))
    {
        if(n==0) break;
        init();
        make();
    }
    return 0;
}

时间: 2024-10-19 12:04:55

poj2002 hash+数学的相关文章

【POJ】Parallelogram Counting(HASH,数学之平行四边形)

Parallelogram Counting 题意:输入t表示有t组数据 每组数据输入一个数n,表示有n个点 然后有n行,每行是这个点的(x,y) 问这些点能组成多少个平行四边形 思路:求中点,中点一样的是一个平行四边形. 记录同一个中点的个数sum(初始为1),平行四边形数是(sum-1) * sum / 2; #include<iostream> #include<algorithm> using namespace std; typedef long long ll; con

poj2002 (极简单数学/几何+hash)

链接:http://poj.org/problem?id=2002 Squares Time Limit: 3500MS   Memory Limit: 65536K Total Submissions: 21720   Accepted: 8321 Description A square is a 4-sided polygon whose sides have equal length and adjacent sides form 90-degree angles. It is also

POJ 2002 Squares 数学 + 必须hash

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

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

poj2002-Squares(数学+哈希)

---恢复内容开始--- 题意:给n个点,问有多少组四个点能组成正方形. 题解:枚举两个点,通过公式算出另外两个点,然后通过哈希查找另外两个点存不存在. //突然发现好弱,好多基础的算法竟然都不会,哈希这种经典的算法,我貌似基本没怎么做过相关的题0.0 公式是抄网上的,哈希直接用了vector存的,反正时限3500ms 点的哈希就是(x^2+y^2)%MOD AC代码: /************************************** Memory: 924 KB Time: 96

Java提高篇——通过分析 JDK 源代码研究 Hash 存储机制

阅读目录 通过 HashMap.HashSet 的源代码分析其 Hash 存储机制HashMap 的存储实现Hash 算法的性能选项HashMap 的读取实现HashSet 的实现 HashMap 和 HashSet 是 Java Collection Framework 的两个重要成员,其中 HashMap 是 Map 接口的常用实现类,HashSet 是 Set 接口的常用实现类.虽然 HashMap 和 HashSet 实现的接口规范不同,但它们底层的 Hash 存储机制完全一样,甚至 H

HashMap、HashSet源代码分析其 Hash 存储机制

集合和引用 就像引用类型的数组一样,当我们把 Java 对象放入数组之时,并不是真正的把 Java 对象放入数组中,只是把对象的引用放入数组中,每个数组元素都是一个引用变量. 实际上,HashSet 和 HashMap 之间有很多相似之处,对于 HashSet 而言,系统采用 Hash 算法决定集合元素的存储位置,这样可以保证能快速存.取集合元素:对于 HashMap 而言,系统 key-value 当成一个整体进行处理,系统总是根据 Hash 算法来计算 key-value 的存储位置,这样可

通过分析 JDK 源代码研究 Hash 存储机制

通过 HashMap.HashSet 的源代码分析其 Hash 存储机制 实际上,HashSet 和 HashMap 之间有很多相似之处,对于 HashSet 而言,系统采用 Hash 算法决定集合元素的存储位置,这样可以保证能快速存.取集合元素:对于 HashMap 而言,系统 key-value 当成一个整体进行处理,系统总是根据 Hash 算法来计算 key-value 的存储位置,这样可以保证能快速存.取 Map 的 key-value 对. 在介绍集合存储之前需要指出一点:虽然集合号称

常见hash算法的原理(转)

常见hash算法的原理 散列表,它是基于快速存取的角度设计的,也是一种典型的“空间换时间”的做法.顾名思义,该数据结构可以理解为一个线性表,但是其中的元素不是紧密排列的,而是可能存在空隙. 散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构.也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度.这个映射函数叫做散列函数,存放记录的数组叫做散列表. 比如我们存储70个元素,但我们可能为这70个元素申请了100个元素的空间.7