POJ2002 Squares(枚举)

题目链接

分析:

普遍的做法是:先枚举两个点,通过数学公式得到另外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;
}
原文地址:https://www.cnblogs.com/tanhehe/p/3273066.html