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的更多相关文章

  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. echarts中的option.legend.data has not been defined.

    1.错误描述 2.错误原因 var map = function(mapData){ require( [ 'echarts', 'echarts/chart/map' ], function (ec ...

  2. Caused by: java.sql.SQLException: Operand should contain 1 column(s)

    1.错误描述 [ERROR:]2015-05-05 15:48:55,847 [异常拦截] org.hibernate.exception.DataException: error executing ...

  3. 不同WINDOWS平台下磁盘逻辑扇区的直接读写

    不同WINDOWS平台下磁盘逻辑扇区的直接读写 关键字:VWIN32.中断.DeviceIoControl 一.概述 在DOS操作系统下,通过BIOS的INT13.DOS的INT25(绝对读).INT ...

  4. JSP常见的三个编译指令

    JSP常见的三个编译指令 1.page指令   是针对当前页面的指令 2.include指令    用于指定包含另一个页面 3.taglib指令    用于定义和访问自定义标签

  5. Android热修复技术原理详解(最新最全版本)

    本文框架 什么是热修复? 热修复框架分类 技术原理及特点 Tinker框架解析 各框架对比图 总结   通过阅读本文,你会对热修复技术有更深的认知,本文会列出各类框架的优缺点以及技术原理,文章末尾简单 ...

  6. 浅析Java 8新特性Method Reference

    什么是方法引用 我们知道了什么是Lambda Expression以及如何使用,那么,Method References又是什么呢?Oracle Java Docs中这样说: They are com ...

  7. 【BZOJ1997】Planar(2-sat)

    [BZOJ1997]Planar(2-sat) 题面 BZOJ 题解 很久没做过\(2-sat\)了 今天一见,很果断的就来切 这题不难呀 但是有个玄学问题: 平面图的性质:边数\(m\)的最大值为\ ...

  8. [SCOI2008]奖励关

    题面在这里 题意 不好描述.....大家还是看luogu上的吧(资磁洛谷!) sol \(n<=15\)的良心数据肯定是状压啦 只是设状态的时候有点头疼 首先思考我们在无法预知之后宝物的情况下如 ...

  9. El表达式的判断字符串的长度和截取,日期时间的格式化

    <c:if test="${fn:length(each.wii_name) >= 20}"> ${fn:substring(each.wii_name, 0,2 ...

  10. C#多线程编程序--聊聊线程

    这篇文章主要给您讲解几个基本问题,什么是线程?为什么要用线程?线程万能?这几个问题.我这篇博客是在该系列另外几篇博客之后写的,之所以不往下继续写,而是回到最初的问题,是因为我感觉到我没有很好的讲解开头 ...