[poj2002]Squares_hash
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。上下的就是细节的事情了。
最后,附上丑陋的代码... ...
- #include <iostream>
- #include <cstdio>
- #include <cstring>
- #include <algorithm>
- #define SIZE 4000010
- #define mod 99991//关于hash的mod数
- using namespace std;
- typedef long long ll;
- int head[2*SIZE];
- int tot;//总点数
- int nxt[2*SIZE];
- struct Node
- {
- int x;
- int y;
- }poi[1001000];//单个的点
- Node val[SIZE];//hash中点的横纵坐标
- void insert(int a)//插入一个点
- {
- int value=(poi[a].x*poi[a].x%mod+poi[a].y*poi[a].y%mod)%mod;
- tot++;
- nxt[tot]=head[value];
- head[value]=tot;
- val[tot].x=poi[a].x;
- val[tot].y=poi[a].y;
- }
- bool find(int x,int y)//寻找横纵坐标分别为x,y的点是否存在
- {
- int value=(x*x%mod+y*y%mod)%mod;
- for(int i=head[value];i;i=nxt[i])
- {
- if(poi[i].x==x&&poi[i].y==y) return true;
- }
- return false;
- }
- ll ans=0;//统计答案
- void original()//初始化
- {
- tot=0;
- memset(head,0,sizeof head);
- memset(poi,0,sizeof poi);
- ans=0;
- }
- int main()
- {
- ans=0;
- int n;
- while(1)
- {
- original();
- scanf("%d",&n);
- if(!n) return 0;
- for(int i=1;i<=n;i++)
- {
- scanf("%d%d",&poi[i].x,&poi[i].y);
- insert(i);
- }
- int x1=0;int y1=0;
- int x2=0;int y2=0;
- int x3=0;int y3=0;
- int x4=0;int y4=0;
- for(int i=1;i<=n;i++)//枚举两个点,判断是否存在相应的正方形
- {
- x1=poi[i].x;y1=poi[i].y;
- for(int j=i+1;j<=n;j++)//由于我check的方式是采取continue的方式,所以需要写两个
- { //关于j的for循环
- x2=poi[j].x;y2=poi[j].y;
- if(x1==x2&&y1==y2) continue;
- x3=x1-y2+y1;
- y3=y1+x2-x1;
- if(!find(x3,y3)) continue;
- x4=x2-y2+y1;
- y4=y2+x2-x1;
- if(!find(x4,y4)) continue;
- ans++;
- }
- for(int j=i+1;j<=n;j++)
- {
- x2=poi[j].x;y2=poi[j].y;
- if(x1==x2&&y1==y2) continue;
- x3=x1-y1+y2;
- y3=y1+x1-x2;
- if(!find(x3,y3)) continue;
- x4=x2-y1+y2;
- y4=y2+x1-x2;
- if(!find(x4,y4)) continue;
- ans++;
- }
- }
- printf("%lld\n",ans/4);//不要忘记答案除以4
- }
- }
小结:我们并不能枚举一条边然后向一个方向枚举,证明在此省略。
不要忘记如果枚举的两个点坐标相同,那么答案是一定会增加的,所以我们将这样的情况舍去。
[poj2002]Squares_hash的更多相关文章
- POJ-2002 Squares---绕点旋转+Hash
题目链接: https://vjudge.net/problem/POJ-2002 题目大意: 有一堆平面散点集,任取四个点,求能组成正方形的不同组合方式有多少. 相同的四个点,不同顺序构成的正方形视 ...
- [POJ2002]Squares(计算几何,二分)
题目链接:http://poj.org/problem?id=2002 给定一堆点,求这些点里哪些点可以构成正方形,题目给定n<=1000,直接枚举四个点是肯定会超时的,因此要做一些优化. 有公 ...
- Poj2002 Squares
题意描述:有一堆平面散点集,任取四个点,求能组成正方形的不同组合方式有多少.相同的四个点,不同顺序构成的正方形视为同一正方形. 思路变迁: 1.最简单的方法,直接暴力搜索,即依次取四个顶点,根据其坐标 ...
- POJ2002 Squares(枚举)
题目链接. 分析: 普遍的做法是:先枚举两个点,通过数学公式得到另外2个点,使得这四个点能够成正方形.然后检查散点集中是否存在计算出来的那两个点,若存在,说明有一个正方形. 但这种做法会使同一个正方形 ...
- POJ2002 二分查找&哈希
问题重述: 给定整数n,以及n个点的坐标xi, yi.求这n个点可以组成的正方形的数目(每个点可重复使用). 分析: 根据正方形的性质,给定两个点就能确定可能构成的两个正方形的另外两个顶点.因此,只需 ...
- poj2002 Squares(hash+折半枚举)
Description A square is a 4-sided polygon whose sides have equal length and adjacent sides form 90-d ...
- poj2002 数正方形 (哈希+几何)
题目传送门 题目大意:给你一堆点,问你能组成几个正方形. 思路:一开始想的是用对角线的长度来当哈希的key,但判断正方形会太复杂,然后就去找了一下正方形的判断方法,发现 已知: (x1,y1) (x2 ...
- poj2002 hash+邻接表优化Squares
Squares Time Limit: 3500MS Memory Limit: 65536K Total Submissions: 17487 Accepted: 6643 Descript ...
- POJ-2002 Squares,哈希模板+数学公式!
Squares 题意:二维坐标轴给出n个点求有多少个正方形. 要是平时做比赛的话毫无疑问会 ...
随机推荐
- SQL注入攻击三部曲之进阶篇
SQL注入攻击三部曲之进阶篇 通过入门篇的学习,我们知道了SQL注入攻击的判断方法,但是如果想侵入网站,获取网站的机密内容,那么仅靠入门篇的知识是无法达到的.本篇文章我们将进一步的分析SQL注入攻击. ...
- JBoss启动项目报错
具体报错如下: WARNING: -logmodule is deprecated. Please use the system property 'java.util.logging.manager ...
- java.lang.NullPointerException: No FileItemFactory has been set.
1.错误描述 java.lang.NullPointerException: No FileItemFactory has been set. at org.apache.commons.fileup ...
- 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 时加一 ...
- C#图解教程 第十九章 LINQ
LINQ 什么是LINQLINQ提供程序 匿名类型 方法语法和查询语法查询变量查询表达式的结构 from子句join子句什么是联结查询主体中的from-let-where片段 from子句let子句w ...
- Python Cookbook(第3版)中文版:15.16 不确定编码格式的C字符串
15.16 不确定编码格式的C字符串¶ 问题¶ 你要在C和Python直接来回转换字符串,但是C中的编码格式并不确定. 例如,可能C中的数据期望是UTF-8,但是并没有强制它必须是. 你想编写代码来以 ...
- Labview中嵌入flex/flash
将flash动画作为ActiveX文档插入LabVIEW程序的前面板的方法 (1)在前面板插入Controls的ActiveX Container控件. (2)在Container控件上单击鼠标右键, ...
- FFT [TPLY]
FFT [TPLY] 题目链接 https://www.luogu.org/problemnew/show/1919 https://www.luogu.org/problemnew/show/380 ...
- POJ 2187 Beauty Contest(凸包,旋转卡壳)
题面 Bessie, Farmer John's prize cow, has just won first place in a bovine beauty contest, earning the ...
- [BZOJ2503][HAOI2006]均分数据
BZOJ Luogu sol 如果已经确定了一个序列,现要求把这个序列分成m个连续段作为答案,那么就可以用一个显而易见的DP DP显然可以得到当前序列下的最优解. 所以模拟退火瞎JB改一改序列每次DP ...