poj2002 哈希

来源:互联网 发布:linux网络编程工作 编辑:程序博客网 时间:2024/06/13 14:58
Squares
Time Limit: 3500MS Memory Limit: 65536KTotal Submissions: 17666 Accepted: 6735

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 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.

Input

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.

Output

For each test case, print on a line the number of squares one can form from the given stars.

Sample Input

41 00 11 10 090 01 02 00 21 22 20 11 12 14-2 53 70 05 20

Sample Output

161

Source

先枚举两个点,通过数学公式得到另外2个点,使得这四个点能够成正方形。然后检查散点集中是否存在计算出来的那两个点,若存在,说明有一个正方形。但这种做法会使同一个正方形按照不同的顺序被枚举了四次,因此最后的结果要除以4.

已知: (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)

 
可以用向量坐标来证明   对角线上俩坐标已知求另一条对角线坐标

标记点x y时,key = (x^2+y^2)%prime

解决的地址冲突的方法,我使用了 链地址法


#include<iostream>  //1500K 1000MS#include<cstdio>#include<cstring>#include<cmath>#define F 19999using namespace std;struct zuo{    int x,y;} p[20001];struct node{    int x,y;    node *next;}*head[20001];int n;int KK(zuo p1){    int key=(p1.x*p1.x+p1.y*p1.y)%F;    return key;}int Build(int k)  //建立{    int key=KK(p[k]);    if(!head[key])    {        head[key]=new node;        head[key]->next=NULL;        node *q;        q=new node;        q->x=p[k].x;        q->y=p[k].y;        q->next=NULL;        head[key]->next=q;    }    else    {        node *q,*top;        top=head[key];        q=head[key]->next;        while(q)        {            q=q->next;            top=top->next;        }        q=new node;        q->next=NULL;        q->x=p[k].x;        q->y=p[k].y;        top->next=q;    }    return 0;}int Count(zuo p1,zuo p2)  //统计{    int key1=KK(p1);    int flag=0;    int key2=KK(p2);    if(head[key1]&&head[key2]) //判断p1,p2是否在哈希表里    {        node *q=head[key1];        while(q)        {            if(q->x==p1.x&&q->y==p1.y)            {                flag=1;                break;            }            q=q->next;        }        if(flag==0)            return 0;        else        {            node *q=head[key2];            while(q)            {                if(q->x==p2.x&&q->y==p2.y)                {                    return 1;                }                q=q->next;            }        }    }    return 0;}int main(){    while(~scanf("%d",&n))    {        memset(head,0,sizeof(head));        if(!n)            break;        for(int i=0; i<n; i++)        {            scanf("%d%d",&p[i].x,&p[i].y);            Build(i);        }        int num=0;        for(int i=0; i<n; i++)        {            for(int j=i+1; j<n; j++)            {                zuo p1,p2;                p1.x=p[i].x+(p[i].y-p[j].y);                p1.y=p[i].y-(p[i].x-p[j].x);                p2.x=p[j].x+(p[i].y-p[j].y);                p2.y=p[j].y-(p[i].x-p[j].x);                num+=Count(p1,p2);                p1.x=p[i].x-(p[i].y-p[j].y);                p1.y=p[i].y+(p[i].x-p[j].x);                p2.x=p[j].x-(p[i].y-p[j].y);                p2.y=p[j].y+(p[i].x-p[j].x);                num+=Count(p1,p2);            }        }        printf("%d\n",num/4);    }}


1 0
原创粉丝点击