OpenJ_Bailian - 2805:正方形 - csdn博客

OpenJ_Bailian - 2805:正方形 - csdn博客

OpenJ_Bailian - 2805:正方形


给出平面上一些点的坐标,统计由这些点可以组成多少个正方形。注意:正方形的边不一定平行于坐标轴。
Input
输入包括多组测试数据。每组的第一行是一个整数n (1 <= n <= 1000),表示平面上点的数目,接下来n行,每行包括两个整数,分别给出一个点在平面上的x坐标和y坐标。输入保证:平面上点的位置是两两不同的,而且坐标的绝对值都不大于20000。最后一组输入数据中n = 0,这组数据表示输入的结束,不用进行处理。
Output
对每组输入数据,输出一行,表示这些点能够组成的正方形的数目。
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

  • 解题思路:这道题直接先对所有的点排序,然后直接枚举两个点,然后从所有的点中查找是否能够组成正方形的另外两个点。仔细想过后发现,对于每个正方行如果知道两个点,确定这两个点的相对位置,那么这个正方形就唯一确定了

初次读题时不会,看到人家有排序时突然就明白了。咳咳,就当这代码练练熟练度了

//我在这里用来判断正方形初始两边的相对位置是正方形的左边
//因此,要使正方行唯一确定,那么剩下两个点的x坐标偏大,y左边偏小
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
struct node{//存储坐标信息
	int x,y;
	bool operator<(const node &m)const
	{
		if(x!=m.x)return x<=m.x;
		return y<=m.y;
	}
};
vector<node> G;
bool fun(node e)//查找函数,又来判断是否能够查到剩下两个点
{
	int l=0,r=G.size();
	int a,b;
	while(r-l>1)
	{
		int mid = (l+r)/2;
		if(G[mid].x<e.x)l=mid;
		else r=mid;
	}
	a=r;
	l=a;r=G.size();
	while(r-l>1)
	{
		int mid = (l+r)/2;
		if(G[mid].x >e.x)r=mid;
		else l=mid;
	}
	b=r;
	while(b-a>1)
	{
		int mid = (a+b)/2;
		if(G[mid].y >e.y)b=mid;
		else a=mid;
	}
	if(G[a].x==e.x&&G[a].y==e.y)
	return true;
	else return false;
}
int main()
{
	int n;
	while(cin>>n,n!=0)
	{
		G.clear();
		for(int i=0;i<n;i++){
			node e;cin>>e.x>>e.y;
			G.push_back(e);
		}
		sort(G.begin(),G.end());
		int ans=0;
		for(int i=0;i<G.size();i++)
			for(int j=i+1;j<G.size();j++)
			{
				node e1=G[i];node e2=G[j];
				node e3,e4;
				//确定剩下两个点的坐标e3和e4
				e3.x=e1.x+e2.y-e1.y;
				e3.y=e1.y-e2.x+e1.x;
				e4.x=e2.x+e2.y-e1.y;
				e4.y=e2.y-e2.x+e1.x;
				int a,b,c,d;
				//判断是否能够查到
				if(fun(e3)&&fun(e4)&&e3.x>e1.x){
					ans++;//cout<<"i:"<<i<<"---j:"<<j<<endl;
				}
			}
		cout<<ans<<endl;
	}
	return 0;
}

有喜欢的朋友可以点下关注O(∩_∩)O哈!,以后会努力进步的

posted @ 2018-06-24 19:41 i-Curve 阅读( ...) 评论( ...) 编辑 收藏
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值