二分应用

题目描述

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

一个二分的算法,通过枚举出对角线的坐标,来确定一个正方形,判断另一个对角线上的坐标是否在该范围内
来确定该正方形是否满足条件

闲话不多说,上代码:

#include<stdio.h>
#include<algorithm>
#include<math.h>
int n;
typedef struct ju
{
	double x,y;
}J;
J ju[1005];
bool cmp(J a,J b)
{
	if(a.x==b.x)
	{
		return a.y<b.y;
	}
	else return a.x<b.x;
}
bool findd(double xx,double yy)
{
	int da=n,xiao=-1,mid;
	while(da-xiao>1)
	{
		mid=(da+xiao)/2;
		if(fabs(ju[mid].x-xx)<1e-9&&fabs(ju[mid].y-yy)<1e-9)
		{
			return true;
		}
		else if(ju[mid].x-xx>1e-9||(fabs(ju[mid].x-xx)<1e-9&&ju[mid].y-yy>1e-9))
		{
			da=mid;
		}
		else xiao=mid;
	}
	return false;
}
int main()
{
	while(1)
	{
		int num=0;
		scanf("%d",&n);
		if(n==0)
		{
			break;
		}
		for(int i=0;i<n;i++)
		{
			scanf("%lf%lf",&ju[i].x,&ju[i].y);
		}
		std::sort(ju,ju+n,cmp);
		for(int i=0;i<n;i++)
		{
			for(int j=i+1;j<n;j++)
			{
				if(i==j)continue;
				double xx,yy;
				xx=(ju[i].x+ju[j].x)/2;
				yy=(ju[i].y+ju[j].y)/2;
				double x1,y1;
				x1=xx-ju[i].x;
				y1=yy-ju[i].y;
				if(findd(xx-y1,yy+x1)&&findd(xx+y1,yy-x1))
				{
					num++;
//					printf("%.2lf %.2lf %.2lf %.2lf %.2lf %.2lf %.2lf %.2lf\n",ju[i].x,ju[i].y,ju[j].x,ju[j].y,xx-y1,yy+x1,xx+y1,yy-x1); 
				}
			}
		}
		printf("%d\n",num/2);
	}
	return 0;
}

应该算关于二分的应用吧

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值