题目来源:poj 2002
给定N个点,求出这些点一共可以构成多少个正方形。
若正方形为ABCD,A坐标为(x1,y1),B坐标为(x2,y2),则很容易可以推出C和D的坐标。对于特定的A和B坐标,C和D可以在线段AB的左边或者右边,即有两种情况。
因此只需要枚举点A和点B,然后计算出两种对应的C和D的坐标,判断是否存在即可。这样计算后得到的答案是正确答案的4倍,因为正方形的4条边都枚举了。
//TLE
#include <iostream>
#include <cstring>
using namespace std;
const int maxn = 1005;
struct node
{
int x, y; //点的属性
} Node[maxn];
int hashTable[1500];
node key_value[1500]; //每个键对应的值
void insert_hash(int x, int y)
{
int mod = (x * x + y * y) % 1499;
while (hashTable[mod])
{
mod = (mod + 1) % 1499;
}
key_value[mod].x = x;
key_value[mod].y = y;
hashTable[mod] = 1;
}
bool search_hash(int x, int y)
{
int mod = (x * x + y * y) % 1499;
while (hashTable[mod])
{
if (key_value[mod].x == x && key_value[mod].y == y)
{
return true;
}
else
{
mod = (mod + 1) % 1499;
}
}
return false;
}
int main()
{
int n;
while (scanf("%d",&n) && n)
{
memset(hashTable, 0, sizeof(hashTable));
for (int i = 0; i < n; i++)
{
scanf("%d %d",&Node[i].x,&Node[i].y);
insert_hash(Node[i].x, Node[i].y);
}
int x3, x4, y3, y4;
int cnt = 0;
for (int i = 0; i < n - 1; i++)
{
for (int j = i + 1; j < n; j++)
{
x3 = Node[j].x + (Node[i].y - Node[j].y);
y3 = Node[j].y + (Node[j].x - Node[i].x);
x4 = Node[i].x + (Node[i].y - Node[j].y);
y4 = Node[i].y + (Node[j].x - Node[i].x);
if (search_hash(x3, y3) && search_hash(x4, y4))
{
cnt++;
}
x3 = Node[j].x - (Node[i].y - Node[j].y);
y3 = Node[j].y - (Node[j].x - Node[i].x);
x4 = Node[i].x - (Node[i].y - Node[j].y);
y4 = Node[i].y - (Node[j].x - Node[i].x);
if (search_hash(x3, y3) && search_hash(x4, y4))
{
cnt++;
}
}
}
cout << cnt / 4 << endl;
}
return 0;
}
AC代码:
先对所有点进行排序,再采用二分查找。
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 1005;
struct node
{
int x, y; //点的属性
} Node[maxn];
int hashTable[1500];
node key_value[1500]; //每个键对应的值
int n;
bool cmp(node n1, node n2)
{
if (n1.x == n2.x)
{
return n1.y < n2.y;
}
return n1.x < n2.x;
}
bool bin_search(int x, int y)
{
int left = 0;
int right = n - 1;
while (left <= right)
{
int mid = left + (right - left) / 2;
if (Node[mid].x == x && Node[mid].y == y)
{
return true;
}
else if (Node[mid].x > x || (Node[mid].x == x && Node[mid].y > y))
{
right = mid - 1;
}
else
{
left = mid + 1;
}
}
return false;
}
int main()
{
while (scanf("%d", &n) && n)
{
memset(hashTable, 0, sizeof(hashTable));
for (int i = 0; i < n; i++)
{
scanf("%d %d", &Node[i].x, &Node[i].y);
}
sort(Node, Node + n, cmp);
int x3, x4, y3, y4;
int cnt = 0;
for (int i = 0; i < n - 1; i++)
{
for (int j = i + 1; j < n; j++)
{
x3 = Node[j].x + (Node[i].y - Node[j].y);
y3 = Node[j].y + (Node[j].x - Node[i].x);
x4 = Node[i].x + (Node[i].y - Node[j].y);
y4 = Node[i].y + (Node[j].x - Node[i].x);
if (bin_search(x3, y3) && bin_search(x4, y4))
{
cnt++;
}
x3 = Node[j].x - (Node[i].y - Node[j].y);
y3 = Node[j].y - (Node[j].x - Node[i].x);
x4 = Node[i].x - (Node[i].y - Node[j].y);
y4 = Node[i].y - (Node[j].x - Node[i].x);
if (bin_search(x3, y3) && bin_search(x4, y4))
{
cnt++;
}
}
}
cout << cnt / 4 << endl;
}
return 0;
}
参考:https://blog.csdn.net/small__snail__5/article/details/80557603
https://blog.csdn.net/iteye_3185/article/details/82031812