poj2002——Squares(hash)

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

4
1 0
0 1
1 1
0 0
9
0 0
1 0
2 0
0 2
1 2
2 2
0 1
1 1
2 1
4
-2 5
3 7
0 0
5 2
0
Sample Output

1
6
1

思想是先找出两个点,看另外两个点是否存在。
已知: (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)

#include <iostream>
#include <cstring>
#include <string>
#include <vector>
#include <queue>
#include <cstdio>
#include <set>
#include <math.h>
#include <algorithm>
#include <queue>
#include <iomanip>
#include <map>
#define INF 0x3f3f3f3f
#define MAXN 10005
#define Mod 20007
using namespace std;
int n,head[20007],next[20007],m;
struct Node
{
    int x,y;
};
Node star[3000];
void add(int i)
{
    int key=(star[i].x*star[i].x+star[i].y*star[i].y)%Mod;
    next[m]=head[key];
    star[m].x=star[i].x;
    star[m].y=star[i].y;
    head[key]=m++;
}
int find(int x,int y)
{
    int key=(x*x+y*y)%Mod;
    for(int i=head[key];i!=-1;i=next[i])
    {
        if(star[i].x==x&&star[i].y==y)
            return i;
    }
    return -1;
}
bool cmp(Node a,Node b)
{
    if(a.x!=b.x)
        return a.x<b.x;
    return a.y<b.y;
}
int main()
{
    while(~scanf("%d",&n)&&n)
    {
        memset(head,-1,sizeof(head));
        memset(next,0,sizeof(next));
        m=1005;
        for(int i=0; i<n; ++i)
        {
            scanf("%d%d",&star[i].x,&star[i].y);
            add(i);
        }
        sort(star,star+n,cmp);
        int ans=0;
        for(int i=0;i<n;++i)
        {
            for(int j=i+1;j<n;++j)
            {
                int x1,y1,x2,y2;
                x1=star[i].x-star[j].y+star[i].y;
                y1=star[i].y+star[j].x-star[i].x;
                if(find(x1,y1)==-1)
                    continue;
                x2=star[j].x-star[j].y+star[i].y;
                y2=star[j].y+star[j].x-star[i].x;
                if(find(x2,y2)==-1)
                    continue;
                ans++;
            }
        }
        printf("%d\n",ans/2);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值