题目大意:给你n个点 问能组成多少个不同的正方形
思路:枚举2个点 由全等三角形得到另外2点坐标 二分查找这2个点是否存在
已知两个点,然后做出两个全等三角形。之后就得出结论(x1+|y1-y2|, y1+|x1-x2|),(x2+|y1-y2|,y2+|x1-x2|)。
二分查找法
#include<stdio.h>
#include<iostream>
#include<string>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
const int maxn = 1005;
const int inf = 1<<30;
int n,ans;
struct Node
{
int x,y;
}point[maxn],c,d;
bool cmp( Node a,Node b )
{
if( a.x == b.x )
return a.y < b.y;
else
return a.x < b.x;
}
void getPoint( Node &a,Node &b )
{
c.x = a.x + (a.y-b.y);
c.y = a.y + (b.x-a.x);
d.x = b.x + (a.y-b.y);
d.y = b.y + (b.x-a.x);
}
bool find( Node s )
{
int ld = 0,rd = n-1,mid;
while( ld <= rd )
{
mid = (ld+rd)>>1;
if( s.x == point[mid].x && s.y == point[mid].y )
return true;
if( s.x < point[mid].x || ( s.x == point[mid].x && s.y < point[mid].y ) )
rd = mid-1;
else
ld = mid + 1;
}
return false;
}
void fun()
{
for( int i = 0; i < n; i ++ ){
for( int j = i+1; j < n; j ++ ){
getPoint( point[i],point[j] );
if( find(c) && find(d) )
ans ++;
}
}
}
int main()
{
//freopen("data.txt","r",stdin);
while( scanf("%d",&n) != EOF,n )
{
for( int i = 0; i < n; i ++ )
{
scanf("%d%d",&point[i].x,&point[i].y);
}
sort( point,point+n,cmp );
ans = 0;
fun();
printf("%d\n",ans/2);
}
return 0;
}
Hash
#include<stdio.h>
#include<iostream>
#include<string>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
const int maxn = 1005;
const int inf = 1<<30;
int n,ans;
struct Node
{
int x,y;
}point[maxn],c,d;
int Hash[maxn*40],Next[maxn]; //已点|x+y|为下标 hash用链接表形式解决冲突
bool cmp( Node a,Node b )
{
if( a.x == b.x )
return a.y < b.y;
else
return a.x < b.x;
}
void getPoint( Node &a,Node &b )
{
c.x = a.x + (a.y-b.y);
c.y = a.y + (b.x-a.x);
d.x = b.x + (a.y-b.y);
d.y = b.y + (b.x-a.x);
}
bool find( Node s )
{
int key = abs( s.x + s.y );
int k = Hash[key];
while( k != -1 )
{
if( point[k].x == s.x && point[k].y == s.y )
return true;
k = Next[k];
}
return false;
}
void fun()
{
for( int i = 0; i < n; i ++ ){
for( int j = i+1; j < n; j ++ ){
getPoint( point[i],point[j] );
if( find(c) && find(d) )
ans ++;
}
}
}
int main()
{
//freopen("data.txt","r",stdin);
while( scanf("%d",&n) != EOF,n )
{
for( int i = 0; i < n; i ++ )
scanf("%d%d",&point[i].x,&point[i].y);
sort( point,point+n,cmp );
memset( Hash,-1,sizeof(Hash) );
int key;
for( int i = 0; i < n; i ++ )
{
key = abs( point[i].x + point[i].y );
Next[i] = Hash[key];
Hash[key] = i;
}
ans = 0;
fun();
printf("%d\n",ans/2);
}
return 0;
}