POJ 2002 Squares

本文探讨了如何从一组星空坐标中找出所有可能形成的正方形。通过哈希表技术优化,实现高效查找并计算出正方形数量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Description

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

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

Input

The input consists of a numberof 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 thex and y coordinates (two integers) of each point. You may assume that thepoints 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 aline 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

 

题目简介:给出n个点的坐标,判断这些点一共可以组成多少个正方形。

方法:哈希表。

      正方形点的求法。已知(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);

 

用(N.x*2+N.y+60000)%60000处理冲突。

 

 

#include<iostream>
#include<cstdio>
#include<list>
using namespace std;

class node
{
public:
	int x, y;
}num[1010];


class HASH
{
public:
	list<node> Hash[60000];

	void Insert(node N)
	{
		Hash[(N.x*2+N.y+60000)%60000].push_back(N);
	}

	void Clear()
	{
		for(int i = 0;i<60000;i++)
		{
			Hash[i].clear();
		}
	}

    int find(node N)
	{
		int target = (N.x*2+N.y+60000)%60000;
		for(list<node>::iterator it = Hash[target].begin();it!=Hash[target].end();it++)
		{
			if(it->x==N.x&&it->y==N.y)
			{
				return 1;
			}
		}
		return 0;
	}
}My_hash;

int main()
{
	int n, i, j;
	while(scanf("%d",&n),n)
	{
		My_hash.Clear();
		for(i = 0;i<n;i++)
		{
			node N;
			scanf("%d%d",&N.x, &N.y);
			num[i] = N;
			My_hash.Insert(N);
		}

		int count = 0;
		for(i = 0;i<n;i++)
		{
			for(j = i+1;j<n;j++)
			{
				node t1, t2;
				t1.x=num[i].x + num[i].y - num[j].y;
				t1.y=num[i].y - num[i].x + num[j].x;
				t2.x=num[j].x + num[i].y - num[j].y;
				t2.y=num[j].y - num[i].x + num[j].x;
				if(My_hash.find(t1)&&My_hash.find(t2))
				{
					count++;
				}

				t1.x=num[i].x - num[i].y + num[j].y;
				t1.y=num[i].y + num[i].x - num[j].x;
				t2.x=num[j].x - num[i].y + num[j].y;
				t2.y=num[j].y + num[i].x - num[j].x;
				if(My_hash.find(t1)&&My_hash.find(t2))
				{
					count++;
				}
			}
		}

		printf("%d\n",count/4);
	}
	return 0;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值