zoukankan      html  css  js  c++  java
  • [POJ2002]Squares(计算几何,二分)

    题目链接:http://poj.org/problem?id=2002

    给定一堆点,求这些点里哪些点可以构成正方形,题目给定n<=1000,直接枚举四个点是肯定会超时的,因此要做一些优化。

    有公式,已知两个点在正方形对角,分别是(x1,y1)和(x2,y2),那么围成正方形后另外两个点(x3,y3)和(x4,y4)分别为:

    x3 = x2 - (x2 - y1)
    y3 = x2 + (x2 - x1)
    x4 = x1 - (x2 - y1)
    y4 = y1 + (x2 - x1)

    那么我们需要枚举两个点,最后推算出这两个点和哪两个点可以围成正方形,然后再去查看剩下的点集里是否存在这两个点。我先排序,再做的二分查找,这个题也可以用hash去做,通过hash可以在O(1)的时间内确定是否存在,更加快捷。特别需要注意的是,假如存在一个正方形,那么必然会枚举到这里面的分别两条边。这个时候需要除以2即可。

     1 #include <algorithm>
     2 #include <iostream>
     3 #include <iomanip>
     4 #include <cstring>
     5 #include <climits>
     6 #include <complex>
     7 #include <fstream>
     8 #include <cassert>
     9 #include <cstdio>
    10 #include <bitset>
    11 #include <vector>
    12 #include <deque>
    13 #include <queue>
    14 #include <stack>
    15 #include <ctime>
    16 #include <set>
    17 #include <map>
    18 #include <cmath>
    19 
    20 using namespace std;
    21 
    22 const int maxn = 1010;
    23 typedef struct Point {
    24     int x, y;
    25     Point() {}
    26     Point(int xx, int yy) : x(xx), y(yy) {}
    27 }Point;
    28 int n, ans;
    29 Point p[maxn];
    30 
    31 bool cmp(Point a, Point b) {
    32     if(a.x == b.x) return a.y < b.y;
    33     return a.x < b.x;
    34 }
    35 
    36 bool bs(int x, int y) {
    37     int ll = 0, rr = n, mm;
    38     while(ll <= rr) {
    39         mm = (ll + rr) >> 1;
    40         if(p[mm].x == x && p[mm].y == y) return 1;
    41         else if(cmp(p[mm], Point(x, y))) ll = mm + 1;
    42         else rr = mm - 1;
    43 
    44     }
    45     return 0;
    46 }
    47 
    48 int main() {
    49     // freopen("in", "r", stdin);
    50     int x3, y3, x4, y4;
    51     while(~scanf("%d", &n) && n) {
    52         ans = 0;
    53         for(int i = 0; i < n; i++) {
    54             scanf("%d%d", &p[i].x, &p[i].y);
    55         }
    56         sort(p, p+n, cmp);
    57         for(int i = 0; i < n; i++) {
    58             for(int j = i + 1; j < n; j++) {
    59                 x3 = p[j].x - (p[j].y - p[i].y);
    60                 y3 = p[j].y + (p[j].x - p[i].x);
    61                 x4 = p[i].x - (p[j].y - p[i].y);
    62                 y4 = p[i].y + (p[j].x - p[i].x);
    63                 if(bs(x3, y3) && bs(x4, y4)) ans++;
    64             }
    65         }
    66         printf("%d
    ", ans / 2);
    67     }
    68     return 0;
    69 }
  • 相关阅读:
    Anaconda+用conda创建python虚拟环境
    Linux安装matlab及简单操作
    Matlab2016b 版本knnclassify函数在Matlab2019b的替换及解决方案
    WIN TO GO实现win10系统迁移
    ArcMap高版本文件保存成低版本
    matlab 保存大于2GB数据
    Tensorflow_gpu + anconda3_3.4.2 +keras2.1.1 + CUDA8.0+CUDNN5.1
    B
    A
    POJ I Think I Need a Houseboat
  • 原文地址:https://www.cnblogs.com/kirai/p/5463622.html
Copyright © 2011-2022 走看看