[POJ 2002]Squares[二分][数学]

来源:互联网 发布:数据挖掘算法工程师 编辑:程序博客网 时间:2024/04/26 07:55
题目链接:[POJ 2002]Squares[二分][数学]

题意分析:

平面中有n个点,求这些点能组成多少个正方形?

解题思路:

最多1e3个点,四个点枚举肯定超时,必须控制在两个点以内。那么两个点可行吗?下面这幅图可以说明可行:


当一条边确定以后,由等边三角形的特性,旁边的两个点也能枚举出来。

所以有(i是a点,j是b点):

temp.x = p[i].x + (p[i].y - p[j].y);
temp.y = p[i].y + (p[j].x - p[i].x);

temp.x = p[j].x + (p[i].y - p[j].y);
temp.y = p[j].y + (p[j].x - p[i].x);

然后用二分搜索查找点是否在图中即可。

由于经过坐标排序后,每个矩形会被枚举两次,最终答案要除以2。

例如上图,当枚举边cd和边bd时会枚举到上图的矩形。

个人感受:

第一想法是枚举两条边= =。发现也是复杂度其高啊。一条边出其它点,这种做法真是对我等数学渣的摧残啊。

具体代码如下:

#include<algorithm>#include<cctype>#include<cmath>#include<cstdio>#include<cstring>#include<iomanip>#include<iostream>#include<map>#include<queue>#include<set>#include<sstream>#include<stack>#include<string>#define lowbit(x) (x & (-x))#define root 1, n, 1#define lson l, m, rt << 1#define rson m + 1, r, rt << 1  1#define ll long long#define pii pair<int, int>#define pr(x) cout << #x << " = " << (x) << '\n';using namespace std;const int INF = 0x7f7f7f7f;const int MAXN = 1e3 + 111;struct P {    int x, y;    bool operator < (const P &t)const {        if (x == t.x) return y < t.y;        return x < t.x;    }}p[MAXN], temp;bool binary(int l, int r) {    if (l > r) return 0;    int m = (l + r) / 2;    if (p[m].x == temp.x && p[m].y == temp.y) return 1;    else if (temp < p[m]) return binary(l, m - 1);    else return binary(m + 1, r);}int main(){    #ifdef LOCAL    freopen("C:\\Users\\apple\\Desktop\\in.txt", "r", stdin);    #endif    int n;    while (~scanf("%d", &n) && n) {        for (int i = 0; i < n; ++i) scanf("%d%d", &p[i].x, &p[i].y);        sort(p, p + n);        int ans = 0;        for (int i = 0; i < n; ++i) {            for (int j = i + 1; j < n; ++j) {                temp.x = p[i].x + (p[i].y - p[j].y);                temp.y = p[i].y + (p[j].x - p[i].x);                //cout << 1 << ':' << temp.x << ' ' << temp.y << '\n';                if (!binary(0, n - 1)) continue;                temp.x = p[j].x + (p[i].y - p[j].y);                temp.y = p[j].y + (p[j].x - p[i].x);                //cout << 2 << ':' << temp.x << ' ' << temp.y << '\n';                if (!binary(0, n - 1)) continue;                ++ans;            }        }        printf("%d\n", ans/2);    }    return 0;}


0 0