当前位置: 代码迷 >> 综合 >> OpenJ_Bailian - 2805:正方形 - csdn博客
  详细解决方案

OpenJ_Bailian - 2805:正方形 - csdn博客

热度:21   发布时间:2023-12-25 18:48:51.0

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和e4e3.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哈!,以后会努力进步的

  相关解决方案