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.
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
题意:在二维平面上,给你n个点的坐标,求任取四点构成正方形的个数
题解:好吧,暴力O(n^4)又t了……
那么折半枚举吧
枚举两个点连成一条线,然后根据这条线可以得到正方形的另外两个点,根据hash可以快速确定点是否在n个点中,即可以计算出正方形的个数
代码如下:
#include<map> #include<vector> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define inf 0x3f3f3f3f using namespace std; struct node { int x,y; } a[1010]; vector<long long> g[100010]; int n; int cmp(node x,node y) { if(x.x==y.x) { return x.y<y.y; } return x.x<y.x; } int main() { while(scanf("%d",&n)==1&&n) { int ans=0; vector<long long> g[100010]; for(int i=1; i<=n; i++) { scanf("%d%d",&a[i].x,&a[i].y); } sort(a+1,a+n+1,cmp); for(int i=1; i<=n; i++) { long long key=(a[i].x*a[i].x+a[i].y*a[i].y)%99991; g[key].push_back(i); } for(int i=1; i<=n; i++) { for(int j=i+1; j<=n; j++) { int x1,y1,x2,y2; int dx=(a[j].x-a[i].x),dy=(a[j].y-a[i].y); // if(dx<0||dy<0) // { // continue; // } x1=a[i].x-dy; y1=a[i].y+dx; x2=a[j].x-dy; y2=a[j].y+dx; int flag=0; long long key=(x1*x1+y1*y1)%99991; for(int k=0; k<g[key].size(); k++) { if(a[g[key][k]].x==x1&&a[g[key][k]].y==y1) { flag+=1; } } key=(x2*x2+y2*y2)%99991; for(int k=0; k<g[key].size(); k++) { if(a[g[key][k]].x==x2&&a[g[key][k]].y==y2) { flag+=1; } } if(flag==2) { // if(a[i].x==x1&&a[i].y==y1||a[j].x==x2&&a[j].y==y2||a[i].x==x2&&a[i].y==y2||a[j].x==x1&&a[j].y==y1) // { // continue; // } // printf("%d %d\n",dx,dy); // printf("%d %d %d %d %d %d %d %d\n",a[i].x,a[i].y,a[j].x,a[j].y,x1,y1,x2,y2); ans++; } } } printf("%d\n",ans/2); } }