题目链接。
分析:
普遍的做法是:先枚举两个点,通过数学公式得到另外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 = 1000 + 10; const int VAL = 100000; 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) == 1 && n) { st.clear(); for(int i=0; i<n; i++) { scanf("%d %d", &pos[i].x, &pos[i].y); st.insert((LL)pos[i].x*VAL+pos[i].y); } int ans = 0; for(int i=0; i<n; i++) { int x1 = pos[i].x, y1 = pos[i].y; for(int j=i+1; 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 ", ans/4); } return 0; }