• POJ-2002 Squares---绕点旋转+Hash


    题目链接:

    https://vjudge.net/problem/POJ-2002

    题目大意:

    有一堆平面散点集,任取四个点,求能组成正方形的不同组合方式有多少。

    相同的四个点,不同顺序构成的正方形视为同一正方形。

    解题思路:

    直接四个点四个点地枚举肯定超时的,不可取。

    普遍的做法是:先枚举两个点(这两个点是正方形的一条边),通过数学公式得到另外2个点,使得这四个点能够成正方形。然后检查散点集中是否存在计算出来的那两个点,若存在,说明有一个正方形。

    但这种做法会使同一个正方形按照不同的顺序被枚举了四次,因此最后的结果要除以4.

    已知点(x1, y1),(x2, y2),可求出下面两种可能

    求出另外两个点之后直接在不在hash表中(之前用二分一直超时)

    关于点(x1, y1)绕点(x0, y0)逆时针旋转β度得到(x2, y2)的公式:

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<string>
      5 #include<map>
      6 #include<set>
      7 #include<cmath>
      8 #include<algorithm>
      9 #include<vector>
     10 #define lowbot(i) (i&(-i))
     11 //#define Rotate(a, b) node(a.x + a.y - b.y, a.y + b.x - a.x)
     12 using namespace std;
     13 typedef long long ll;
     14 const int maxn = 1000 + 10;
     15 const int mod = 9973;
     16 struct node
     17 {
     18     int x, y;
     19     node(){}
     20     node(int x, int y):x(x), y(y){}
     21 };
     22 struct hashtable
     23 {
     24     int x, y;
     25     hashtable * next;
     26     hashtable()
     27     {
     28         next = 0;
     29     }
     30 };
     31 hashtable * Hash[mod];
     32 void Hash_Insert(node a)
     33 {
     34     int key = (a.x * a.x + a.y * a.y) % mod;
     35     if(!Hash[key])
     36     {
     37         hashtable * p = new hashtable;
     38         p->x = a.x;
     39         p->y = a.y;
     40         Hash[key] = p;
     41     }
     42     else
     43     {
     44         hashtable *p = Hash[key];
     45         while(p->next)p=p->next;
     46         hashtable* temp = new hashtable;
     47         temp->x = a.x;
     48         temp->y = a.y;
     49         p->next = temp;
     50     }
     51 }
     52 bool Find(node a)
     53 {
     54     int key = (a.x * a.x + a.y * a.y) % mod;
     55     if(!Hash[key])return false;
     56     else
     57     {
     58         hashtable * temp = Hash[key];
     59         while(temp)
     60         {
     61             if(temp->x == a.x && temp->y == a.y)
     62                 return true;
     63             temp = temp->next;
     64         }
     65     }
     66     return false;
     67 }
     68 node a[maxn];
     69 
     70 node Rotate(node a, node b)//点b绕着点a逆时针旋转90度的坐标
     71 {
     72     int x = (b.x - a.x) * 0 - (b.y - a.y) * 1 + a.x;
     73     int y = (b.x - a.x) * 1 + (b.y - a.y) * 0 + a.y;
     74     return node(x, y);
     75 }
     76 
     77 int main()
     78 {
     79     int n;
     80     while(scanf("%d", &n) != EOF && n)
     81     {
     82         memset(Hash, 0, sizeof(Hash));
     83         for(int i = 1; i <= n; i++)
     84         {
     85             scanf("%d%d", &a[i].x, &a[i].y);
     86             Hash_Insert(a[i]);
     87         }
     88         int ans = 0;
     89         node x, y;
     90         for(int i = 1; i <= n; i++)
     91         {
     92             for(int j = i + 1; j <= n; j++)
     93             {
     94                 x = Rotate(a[i], a[j]);
     95                 y = Rotate(x, a[i]);
     96                 if(Find(x) && Find(y))ans++;
     97                 //cout<<i<<" "<<j<<" "<<x.x<<" "<<x.y<<" "<<y.x<<" "<<y.y<<endl;
     98                 x = Rotate(a[j], a[i]);
     99                 y = Rotate(x, a[j]);
    100                 if(Find(x) && Find(y))ans++;
    101             }
    102         }
    103         printf("%d
    ", ans / 4);
    104     }
    105     return 0;
    106 }
  • 相关阅读:
    Graphviz使用入门教程
    【编译原理笔记】抽象语法树AST图解
    cgo编译参数
    彻底解决Golang获取当前项目绝对路径问题
    udev和rules使用规则
    Linux系统启动U盘制作工具
    udev的rules定制和调试
    为什么变量名不能够以数字开头
    基于GCC的C语言抽象语法树重建与可视化研究
    Java7之后的intern
  • 原文地址:https://www.cnblogs.com/fzl194/p/8949480.html
Copyright © 2020-2023  润新知