题目链接。
分析:
普遍的做法是:先枚举两个点,通过数学公式得到另外2个点,使得这四个点能够成正方形。然后检查散点集中是否存在计算出来的那两个点,若存在,说明有一个正方形。
但这种做法会使同一个正方形按照不同的顺序被枚举了四次,因此最后的结果要除以4.
已知: (x1,y1) (x2,y2)
则: x3=x1+(y1-y2) y3= y1-(x1-x2)
x4=x2+(y1-y2) y4= y2-(x1-x2)
或
x3=x1-(y1-y2) y3= y1+(x1-x2)
x4=x2-(y1-y2) y4= y2+(x1-x2)
直接hash太麻烦,使用set简单些.
AC代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <set> using namespace std; const int maxn = + ;
const int VAL = ; typedef long long LL; set<LL> st; struct Pos {
int x, y;
}pos[maxn]; int main() {
int n, x3, y3, x4, y4; while(scanf("%d", &n) == && n) {
st.clear();
for(int i=; i<n; i++) {
scanf("%d %d", &pos[i].x, &pos[i].y);
st.insert((LL)pos[i].x*VAL+pos[i].y);
} int ans = ; for(int i=; i<n; i++) {
int x1 = pos[i].x, y1 = pos[i].y;
for(int j=i+; j<n; j++) {
int x2 = pos[j].x, y2 = pos[j].y;
x3 = x1+(y1-y2); y3 = y1-(x1-x2);
x4 = x2+(y1-y2); y4 = y2-(x1-x2); if( st.count((LL)x3*VAL+y3) && st.count((LL)x4*VAL+y4)) {
ans++;
} x3 = x1-(y1-y2); y3 = y1+(x1-x2);
x4 = x2-(y1-y2); y4 = y2+(x1-x2); if( st.count((LL)x3*VAL+y3) && st.count((LL)x4*VAL+y4)) {
ans++;
}
}
} printf("%d\n", ans/);
} return ;
}