Squares poj-2002

    题目大意:在笛卡尔坐标系中给出n个点,求这些点可以构成多少个正方形。

    注释:$1\le n\le 10^3$,$-2\cdot 10^3\le x , y\le 2\cdot 10^3$.

      想法:最基本的办法是n个点中枚举三个点,然后用桶判断第四个点是否存在。然后我们想一想这个方法怎么优化,首先,枚举三个点我们可以进而优化成为枚举一条边,然后判断可能出现的两个正方形是否存在,时间复杂度$O(n^2)$。对于空间复杂度,4000*4000的桶显然开不下,我们自然而然想到hash处理。但是横纵坐标还存在负权值,故此我们期望找到一个即不区分正负,但是用能将点期望离散开的hash计算方式。首先想到|x|+|y|。但是这种方式并不能很好的将所有点都离散开,更容易想到x*x+y*y。上下的就是细节的事情了。

    最后,附上丑陋的代码... ...

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <algorithm>
  5. #define SIZE 4000010
  6. #define mod 99991//关于hash的mod数
  7. using namespace std;
  8. typedef long long ll;
  9. int head[2*SIZE];
  10. int tot;//总点数
  11. int nxt[2*SIZE];
  12. struct Node
  13. {
  14. int x;
  15. int y;
  16. }poi[1001000];//单个的点
  17. Node val[SIZE];//hash中点的横纵坐标
  18. void insert(int a)//插入一个点
  19. {
  20. int value=(poi[a].x*poi[a].x%mod+poi[a].y*poi[a].y%mod)%mod;
  21. tot++;
  22. nxt[tot]=head[value];
  23. head[value]=tot;
  24. val[tot].x=poi[a].x;
  25. val[tot].y=poi[a].y;
  26. }
  27. bool find(int x,int y)//寻找横纵坐标分别为x,y的点是否存在
  28. {
  29. int value=(x*x%mod+y*y%mod)%mod;
  30. for(int i=head[value];i;i=nxt[i])
  31. {
  32. if(poi[i].x==x&&poi[i].y==y) return true;
  33. }
  34. return false;
  35. }
  36. ll ans=0;//统计答案
  37. void original()//初始化
  38. {
  39. tot=0;
  40. memset(head,0,sizeof head);
  41. memset(poi,0,sizeof poi);
  42. ans=0;
  43. }
  44. int main()
  45. {
  46. ans=0;
  47. int n;
  48. while(1)
  49. {
  50. original();
  51. scanf("%d",&n);
  52. if(!n) return 0;
  53. for(int i=1;i<=n;i++)
  54. {
  55. scanf("%d%d",&poi[i].x,&poi[i].y);
  56. insert(i);
  57. }
  58. int x1=0;int y1=0;
  59. int x2=0;int y2=0;
  60. int x3=0;int y3=0;
  61. int x4=0;int y4=0;
  62. for(int i=1;i<=n;i++)//枚举两个点,判断是否存在相应的正方形
  63. {
  64. x1=poi[i].x;y1=poi[i].y;
  65. for(int j=i+1;j<=n;j++)//由于我check的方式是采取continue的方式,所以需要写两个
  66. { //关于j的for循环
  67. x2=poi[j].x;y2=poi[j].y;
  68. if(x1==x2&&y1==y2) continue;
  69. x3=x1-y2+y1;
  70. y3=y1+x2-x1;
  71. if(!find(x3,y3)) continue;
  72. x4=x2-y2+y1;
  73. y4=y2+x2-x1;
  74. if(!find(x4,y4)) continue;
  75. ans++;
  76. }
  77. for(int j=i+1;j<=n;j++)
  78. {
  79. x2=poi[j].x;y2=poi[j].y;
  80. if(x1==x2&&y1==y2) continue;
  81. x3=x1-y1+y2;
  82. y3=y1+x1-x2;
  83. if(!find(x3,y3)) continue;
  84. x4=x2-y1+y2;
  85. y4=y2+x1-x2;
  86. if(!find(x4,y4)) continue;
  87. ans++;
  88. }
  89. }
  90. printf("%lld\n",ans/4);//不要忘记答案除以4
  91. }
  92. }

    小结:我们并不能枚举一条边然后向一个方向枚举,证明在此省略。

        不要忘记如果枚举的两个点坐标相同,那么答案是一定会增加的,所以我们将这样的情况舍去。

[poj2002]Squares_hash的更多相关文章

  1. POJ-2002 Squares---绕点旋转+Hash

    题目链接: https://vjudge.net/problem/POJ-2002 题目大意: 有一堆平面散点集,任取四个点,求能组成正方形的不同组合方式有多少. 相同的四个点,不同顺序构成的正方形视 ...

  2. [POJ2002]Squares(计算几何,二分)

    题目链接:http://poj.org/problem?id=2002 给定一堆点,求这些点里哪些点可以构成正方形,题目给定n<=1000,直接枚举四个点是肯定会超时的,因此要做一些优化. 有公 ...

  3. Poj2002 Squares

    题意描述:有一堆平面散点集,任取四个点,求能组成正方形的不同组合方式有多少.相同的四个点,不同顺序构成的正方形视为同一正方形. 思路变迁: 1.最简单的方法,直接暴力搜索,即依次取四个顶点,根据其坐标 ...

  4. POJ2002 Squares(枚举)

    题目链接. 分析: 普遍的做法是:先枚举两个点,通过数学公式得到另外2个点,使得这四个点能够成正方形.然后检查散点集中是否存在计算出来的那两个点,若存在,说明有一个正方形. 但这种做法会使同一个正方形 ...

  5. POJ2002 二分查找&哈希

    问题重述: 给定整数n,以及n个点的坐标xi, yi.求这n个点可以组成的正方形的数目(每个点可重复使用). 分析: 根据正方形的性质,给定两个点就能确定可能构成的两个正方形的另外两个顶点.因此,只需 ...

  6. poj2002 Squares(hash+折半枚举)

    Description A square is a 4-sided polygon whose sides have equal length and adjacent sides form 90-d ...

  7. poj2002 数正方形 (哈希+几何)

    题目传送门 题目大意:给你一堆点,问你能组成几个正方形. 思路:一开始想的是用对角线的长度来当哈希的key,但判断正方形会太复杂,然后就去找了一下正方形的判断方法,发现 已知: (x1,y1) (x2 ...

  8. poj2002 hash+邻接表优化Squares

    Squares Time Limit: 3500MS   Memory Limit: 65536K Total Submissions: 17487   Accepted: 6643 Descript ...

  9. POJ-2002 Squares,哈希模板+数学公式!

                                                           Squares 题意:二维坐标轴给出n个点求有多少个正方形. 要是平时做比赛的话毫无疑问会 ...

随机推荐

  1. SQL注入攻击三部曲之进阶篇

    SQL注入攻击三部曲之进阶篇 通过入门篇的学习,我们知道了SQL注入攻击的判断方法,但是如果想侵入网站,获取网站的机密内容,那么仅靠入门篇的知识是无法达到的.本篇文章我们将进一步的分析SQL注入攻击. ...

  2. JBoss启动项目报错

    具体报错如下: WARNING: -logmodule is deprecated. Please use the system property 'java.util.logging.manager ...

  3. java.lang.NullPointerException: No FileItemFactory has been set.

    1.错误描述 java.lang.NullPointerException: No FileItemFactory has been set. at org.apache.commons.fileup ...

  4. Good Bye 2017 D. New Year and Arbitrary Arrangement

    看了别人的题解 首先这题是一个dp dp[i][j] i是当前有多少个a j是当前有多少个ab子序列 dp[i][j] = dp[i+1][j]*Pa + dp[i][i+j]*Pb; i,j 时加一 ...

  5. C#图解教程 第十九章 LINQ

    LINQ 什么是LINQLINQ提供程序 匿名类型 方法语法和查询语法查询变量查询表达式的结构 from子句join子句什么是联结查询主体中的from-let-where片段 from子句let子句w ...

  6. Python Cookbook(第3版)中文版:15.16 不确定编码格式的C字符串

    15.16 不确定编码格式的C字符串¶ 问题¶ 你要在C和Python直接来回转换字符串,但是C中的编码格式并不确定. 例如,可能C中的数据期望是UTF-8,但是并没有强制它必须是. 你想编写代码来以 ...

  7. Labview中嵌入flex/flash

    将flash动画作为ActiveX文档插入LabVIEW程序的前面板的方法 (1)在前面板插入Controls的ActiveX Container控件. (2)在Container控件上单击鼠标右键, ...

  8. FFT [TPLY]

    FFT [TPLY] 题目链接 https://www.luogu.org/problemnew/show/1919 https://www.luogu.org/problemnew/show/380 ...

  9. POJ 2187 Beauty Contest(凸包,旋转卡壳)

    题面 Bessie, Farmer John's prize cow, has just won first place in a bovine beauty contest, earning the ...

  10. [BZOJ2503][HAOI2006]均分数据

    BZOJ Luogu sol 如果已经确定了一个序列,现要求把这个序列分成m个连续段作为答案,那么就可以用一个显而易见的DP DP显然可以得到当前序列下的最优解. 所以模拟退火瞎JB改一改序列每次DP ...