[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个点求有多少个正方形. 要是平时做比赛的话毫无疑问会 ...
随机推荐
- hi3531结构: VB_CONF_S
定义视频缓存池属性结构体. typedef struct hiVB_CONF_S { HI_U32 u32MaxPoolCnt; /* max count of pools, (0,VB ...
- VC获取并修改计算机屏幕分辨率
//获取分辨率 int m_nWindwMetricsX = ::GetSystemMetrics(SM_CXSCREEN); int m_nWindwMetricsY = : ...
- LINQ 按多个字段排序(orderby、thenby、Take)
LINQ 按多个字段排序(orderby.thenby.Take) orderby 子句解析为 OrderBy()方法,orderby descending 子句解析为OrderBy Descend ...
- 【原】无脑操作:IDEA + maven + SpringBoot + JPA + Thymeleaf实现CRUD及分页
一.开发环境: 1.windows 7 企业版 2.IDEA 14 3.JDK 1.8 4.Maven 3.5.2 5.MariaDB 6.SQLYog 二.Maven设置: Maven目录下的con ...
- linux iscsi配置
iSCSI 是一种 SAN的设备而 SAN的设备主要是提供 Server 存储体的空间.相较于传统的 SAN 是以光纤为传输媒体而 iSCSI(Internet SCSI)他是 IP-based 的数 ...
- jQuery UI Autocomplete Combobox 配 ASP.NET DropDownList
0.引言 1.起因 一开始使用Autocomplete做了一个自动补全的文本框,如上图.后来因业务需要希望能在这个文本框的边上做个下拉列表按钮,一按就展开所有支持 ...
- docker进阶-搭建私有企业级镜像仓库Harbor
为什么要搭建私有镜像仓库 对于一个刚刚接触Docker的人来说,官方的Docker hub是用于管理公共镜像.既然官方提供了镜像仓库我们为什么还要去自己搭建私有仓库呢?虽然也可以托管私有镜像.我们 ...
- 百度在线编辑器 - PHP获取提交的数据
原文:http://www.upwqy.com/details/14.html 1 我们知道在在百度在线编辑器的demo中. 我们只要在body 里面 加载 script 标签 id="ed ...
- linux 添加ftp用户与登录配置详解
不同类Unix有一定区别 版本不同也有些区别 在linux主机上如何添加ftp用户 (一)修改配置文件 vi /etc/vsftpd/vsftpd.conf 在96行,97,98行 96 chroot ...
- 【技术】关于安卓使用禁用服务(或者是MYANDROIDTOOLS里面的禁用服务)后卡在开机页面的(或者是卡在各种页面的)
目前会出现禁用部分服务后卡在开机页面,导致到手机数据得全部清除在网上找了很久,都没找到还原的方法只好自己开垦新方案了推测:由于格式化DATA分区后,手机可以正常开机,所以认为禁用服务的配置内容保存在D ...