zoukankan      html  css  js  c++  java
  • 2016级算法第三次上机-E.ModricWang's Polygons

    930 ModricWang's Polygons

    思路

    首先要想明白,哪些多边形可能是格点正多边形?

    分情况考虑:

    三角形不可能,因为边长为有理数的正三角形的面积为无理数,而格点三角形的面积为有理数,二者矛盾。

    正四边形毫无疑问是可以的。

    边数>4时,可以考虑无穷递降法:

    以六边形为例,假如整点正六边形存在,一定有边长最小的一个,记作(A_1 A_2 A_3 A_4 A_5 A_6)。以(A_2)为中心,将(A_1)逆时针旋转90度,得到(B_1)。显然也是整点。类似定义(B_2 ... B_6),它们也都是整点。【注:上面用到如下结论:一个整点绕另一个整点旋转90度,得到的点仍然是整点。证明很容易。】如你所见,(B_1 B_2 B_3 B_4 B_5 B_6)是一个更小的整点正六边形,矛盾。

    对于边数>4的其他情况,也可以用类似方法证明。

    参考自这里

    于是该问题就变成了统计格点正四边形的数量。考虑枚举任意两个点形成的线段,那么由这一条线段可以形成的格点正四边形只有两个,并且另外两个点的坐标是可以直接算出来的。因此只要枚举任意两点的组合,验证以这两个点为相邻两点的格点正四边形是否存在即可。

    时间复杂度(O(n^2)),空间复杂度(O(n))

    代码

    #include <bits/stdc++.h>
    #define ll long long
    #define mk make_pair
    #define y1 yyy
    using namespace std;
    
    const int N = 1e3 + 5;
    
    map<pair<int, int>, bool> M;
    int x[N], y[N], n, ans;
    
    int main() {
      int T;
      while (scanf("%d", &n) != EOF) {
        ans = 0;
        M.clear();
        for (int i = 1; i <= n; i++) {
          scanf("%d %d", x + i, y + i);
          M[mk(x[i], y[i])] = 1;
        }
        for (int i = 1; i <= n; i++) {
          for (int j = i + 1; j <= n; j++) {
            int dx = y[j] - y[i];
            int dy = x[i] - x[j];
            int ok = 0;
            if (M.count(mk(x[i] + dx, y[i] + dy)))
              ok++;
            if (M.count(mk(x[j] + dx, y[j] + dy)))
              ok++;
            if (ok == 2)
              ans++;
            ok = 0;
            if (M.count(mk(x[i] - dx, y[i] - dy)))
              ok++;
            if (M.count(mk(x[j] - dx, y[j] - dy)))
              ok++;
            if (ok == 2)
              ans++;
          }
        }
        printf("%d
    ", ans / 4);
      }
    
  • 相关阅读:
    程序包管理
    磁盘篇
    centos7上常用软件安装
    这个端午
    字节码技术及动态代理
    浅析同步异步阻塞非阻塞
    String拾遗
    Java注解拾遗
    设计模式之总结篇
    设计模式之访问者模式
  • 原文地址:https://www.cnblogs.com/AlvinZH/p/7977907.html
Copyright © 2011-2022 走看看