给出一堆点,求其中正方形的个数。

题目很简单,如果枚举,复杂度为O(n^4),肯定超时,我们利用hash,或者二分来降低复杂度,枚举其中的两个点,然后利用正方形的性质求出其余的两个点,然后判断这两个点是否都存在,如果存在,说明可以组成一个正方形。判断的方式利用hash或者二分都可以,这个题目用的hash,poj3432用的二分。下面的问题就是给出两个点,如何求出其余的两个顶点。

给出两个点(a1,a2),(b1,b2),我们得到其余两个顶点为(a1+(b2-a2),a2-(b1-a1)),(b1+(b2-a2),b2-(b1-a1)),或者
(a1-(b2-a2), a2+(b1-a1)),( b1-(b2-a2), b2+(b1-a1)),我们只考虑一种情况就可以了,否则也是重复计算。这样对于同一个
正方形,每条边都计算了一遍(顶点已经排序),只是我们只计算每条边对应的左上方或者右下方的矩形,这样只有两条边对应的计算了一次,因此
需要将计数/2。

poj2002

代码:

View Code

#include <iostream>#include <cmath>#include <algorithm>#include <stdio.h>using namespace std;const int N=1010;const int M=40010;struct m_point{int x,y;};m_point s[N];int m_hash[M],next[N],n;bool cmp(const m_point &p1,const m_point &p2){if(p1.x < p2.x)return true;if((p1.x == p2.x) && (p1.y < p2.y))return true;return false;}bool isExist(int x,int y){int value=abs(x+y);int index=m_hash[value];while(-1 != index)    {if((s[index].x == x) && (s[index].y == y))return true;        index=next[index];    }return false;}int main(){int i,j,value,new_x,new_y,ans=0;    m_point tmp;while(scanf("%d",&n) && n)    {        ans=0;        memset(next,-1,sizeof(next));        memset(m_hash,-1,sizeof(m_hash));for(i=0;i<n;++i)            scanf("%d%d",&s[i].x,&s[i].y);        sort(s,s+n,cmp);for(i=0;i<n;++i)        {     //hash函数是采用的两个坐标的和,和相同的用类似与链表连接起来            value=abs(s[i].x+s[i].y);            next[i]=m_hash[value];//技巧和图的邻接表存储方式相同            m_hash[value]=i;        }//         for(i=0;i<n;++i)//             cout<<s[i].x<<" "<<s[i].y<<'\t';//         cout<<endl;        for(i=0;i<n;++i)        {for(j=i+1;j<n;++j)            {                tmp.x=s[j].x-s[i].x;                tmp.y=s[j].y-s[i].y;                new_x=s[i].x+tmp.y;                new_y=s[i].y-tmp.x;if(!isExist(new_x,new_y))continue;                new_x=s[j].x+tmp.y;                new_y=s[j].y-tmp.x;if(!isExist(new_x,new_y))continue;                ++ans;            }        }        printf("%d\n",ans/2);    }return 0;}

poj3432

代码:

View Code

#include <iostream>#include <algorithm>#include <stdio.h>using namespace std;const int N=2002;struct m_point{int x,y;};int n;m_point p[N];bool cmp(const m_point &p1,const m_point &p2){if(p1.x < p2.x)return true;if((p1.x == p2.x) && (p1.y < p2.y))return true;return false;}bool find_point(m_point &t){int left=0,right=n,mid;while(left<=right)    {        mid=(left+right)>>1;if((p[mid].x == t.x) && (p[mid].y == t.y))return true;if(cmp(t,p[mid]))            right=mid-1;else            left=mid+1;    }return false;}

int main(){int i,j,ans;    m_point tmp,new_node;while(scanf("%d",&n) != EOF)    {for(i=0;i<n;++i)            scanf("%d%d",&p[i].x,&p[i].y);        sort(p,p+n,cmp);        ans=0;for(i=0;i<n;++i)        {for(j=i+1;j<n;++j)            {                tmp.x=p[j].x-p[i].x;                tmp.y=p[j].y-p[i].y;                new_node.x=p[i].x+tmp.y;                new_node.y=p[i].y-tmp.x;if(!find_point(new_node))continue;                new_node.x=p[j].x+tmp.y;                new_node.y=p[j].y-tmp.x;if(!find_point(new_node))continue;                ++ans;            }        }        printf("%d\n",ans/2);    }return 0;}

转载于:https://www.cnblogs.com/buptLizer/archive/2011/12/03/2274811.html

poj2002 poj3432 正方形个数 (hash,二分)相关推荐

  1. bzoj 1014: [JSOI2008]火星人prefix(splay维护区间+Hash+二分)

    1014: [JSOI2008]火星人prefix Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 7588  Solved: 2429 [Submi ...

  2. 不规则图形数格子的方法_小学数学,怎么数平面图形中长方形与正方形个数

    昨天我们说了线段的两种计数方法,一种是数端点的方法,也叫打枪法,或者叫大炮发射法,另一种是分类法.而且我们着重推荐使用分类法.今天我们继续说说平面图形的计数问题. 今天这里着重说一下,长方形以及正方形 ...

  3. n*m的格子中正方形个数和长方形个数

    问题描述 1.设有一个nm方格的棋盘(1≤m,n≤100). 求出该棋盘中包含多少个正方形.多少个长方形(不包括正方形). 例如:当n=2,m=3时 正方形的个数有8个:即边长为1的正方形有6个: 边 ...

  4. [luoguP2601] [ZJOI2009]对称的正方形(二维Hash + 二分 || Manacher)

    传送门 很蒙蔽,不知道怎么搞. 网上看题解有说可以哈希+二分搞,也有的人说用Manacher搞,Manacher是什么鬼?以后再学. 对于这个题,可以从矩阵4个角hash一遍,然后枚举矩阵中的点,再二 ...

  5. 后缀数组 + Hash + 二分 or Hash + 二分 + 双指针 求 LCP ---- 2017icpc 青岛 J Suffix (假题!!)

    题目链接 题目大意: 就是给你n个串每个串取一个后缀,要求把串拼起来要求字典序最小!! sum_length_of_n≤5e5sum\_length\_of\_n\leq 5e5sum_length_ ...

  6. BZOJ 2084: [Poi2010]Antisymmetry(Hash+二分)

    求一个01序列的子串取反并反转后与原串相同的个数. 很显而易见的是,反转的话只要子串对应的i和n-i+1位相反即可,这个看一下样例能很快看出来. 所以我们正着求一遍hash,反着取反然后求hash. ...

  7. ZZULI 1876: 蛤玮的项链 Hash + 二分

    Time Limit: 6 Sec  Memory Limit: 128 MB Submit: 153  Solved: 11 SubmitStatusWeb Board Description 蛤玮 ...

  8. 1402 后缀数组 (hash+二分)

    描述 后缀数组 (SA) 是一种重要的数据结构,通常使用倍增或者DC3算法实现,这超出了我们的讨论范围.在本题中,我们希望使用快排.Hash与二分实现一个简单的 O(n log^2⁡n ) 的后缀数组 ...

  9. codechef INSQ15_A(hash+二分)

    思路:首先计算字符串s的所有后缀的hash值,然后根据p分离的两个字符串的最长公共子串,使用二分查找.具体代码参考: https://github.com/wuli2496/OJ/blob/maste ...

最新文章

  1. 图像风格迁移也有框架了
  2. 产生0到1之间均匀分布的一个随机数原理与实现
  3. easyUI的中文乱码问题
  4. [转】TCP 三次握手 四次挥手
  5. Michael Dell承诺打造新的EMC/戴尔/VMware工程技术系统
  6. 为什么 jmeter 分布式测试,一定要设置 java.rmi.server.hostname
  7. java中的this关键字详解(图示)
  8. 九、瞰景Smart3D Viewer浏览器
  9. 【SSH密钥生成与使用】
  10. unbuntu安装MySQL
  11. 那些令人发燥的JAVA虚引用
  12. Rancher hosted Kubernetes AKS
  13. 2011-12-21的告别信
  14. MATLAB 机器人工具箱简单教程:(下载及安装)
  15. 洛谷 P4233 射命丸文的笔记 ntt
  16. php蓝牙配对,有用bluez做蓝牙配对吗
  17. SQL 入门,看这篇就够了 ---- 基础篇
  18. linux命令gw,Linux命令行配置IP、GW、DNS
  19. Vue开发常用的工具有哪些?
  20. gff文件_GTF与GFF文件所有操作尽在这里

热门文章

  1. wifi共享大师电脑版_手机开wifi热点,共享网络给电脑,变身4G无线路由器
  2. 功率谱 魏凤英统计程序_频谱、能量谱、功率谱、功率谱估计
  3. php怎么删除所有文件夹,用php删除所有文件,文件夹及其子文件夹
  4. 线性代数可以速成吗_广播/学习吉他速成靠谱吗?真的可以速成吗?
  5. 阿拉德之怒显示服务器错误,阿拉德之怒网络异常怎么办 安装失败怎么办
  6. linux查询数据库sql,SQL Server 跨数据库查询
  7. python compile正则_Python 正则表达式:compile,match
  8. vim配置python开发环境_VIM插件管理及python开发环境配置
  9. windows文件保护_等保测评2.0:Windows安全审计
  10. mysql left join的深入探讨