http://poj.org/problem?id=2002
题意:有 n (n<=1000)个点,问在这 n 个点中能组成多少个正方形。
思路:可先考虑正方形的特性,边 AB 绕 A 点旋转可得到点 C,绕 B 点旋转可得到点 D,点 C 和 点 D 坐标可直接根据全等求出。这样复杂度就可减为 O(n*n),剩下来的就是判断求出的点 C 和点 D 是否在输入的点中,可用 set .
代码:
#include<cstdio>
#include<map>
#include<iostream>
#include <cstdlib>
#include <set>
#include<algorithm>
using namespace std;
const int maxn = 1005;
struct node
{
int x,y;
friend bool operator < (node a,node b){
if(a.x == b.x)
return a.y < b.y;
return a.x < b.x;
}
}list[maxn];
set <node> S;
int yes(node a ,node b)
{
node c1,d1;
int num = 0;
c1.x = a.x - (b.y - a.y);
c1.y = a.y + (b.x - a.x);
d1.x = b.x - (b.y - a.y);
d1.y = b.y + (b.x - a.x);
if(S.find(c1)!=S.end()&&S.find(d1)!=S.end()){
num++;
}
return num;
}
int cmp(node a,node b)
{
if(a.x == b.x)
return a.y>b.y;
return a.x>b.x;
}
int main()
{
int n,i;
while(scanf("%d",&n)!=EOF&&n){
for(i=0;i<n;i++){
scanf("%d %d",&list[i].x,&list[i].y);
S.insert(list[i]);
}
sort(list,list+n,cmp);
int num = 0;
for(i = 0;i < n;i ++){
for(int j = i+1;j<n;j ++){
num+=yes(list[i],list[j]);
}
}
printf("%d\n",num/2);
S.clear();
}
return 0;
}