题目链接:

https://vjudge.net/problem/POJ-2002

题目大意:

有一堆平面散点集,任取四个点,求能组成正方形的不同组合方式有多少。

相同的四个点,不同顺序构成的正方形视为同一正方形。

解题思路:

直接四个点四个点地枚举肯定超时的,不可取。

普遍的做法是:先枚举两个点(这两个点是正方形的一条边),通过数学公式得到另外2个点,使得这四个点能够成正方形。然后检查散点集中是否存在计算出来的那两个点,若存在,说明有一个正方形。

但这种做法会使同一个正方形按照不同的顺序被枚举了四次,因此最后的结果要除以4.

已知点(x1, y1),(x2, y2),可求出下面两种可能

求出另外两个点之后直接在不在hash表中(之前用二分一直超时)

关于点(x1, y1)绕点(x0, y0)逆时针旋转β度得到(x2, y2)的公式:

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<map>
#include<set>
#include<cmath>
#include<algorithm>
#include<vector>
#define lowbot(i) (i&(-i))
//#define Rotate(a, b) node(a.x + a.y - b.y, a.y + b.x - a.x)
using namespace std;
typedef long long ll;
const int maxn = + ;
const int mod = ;
struct node
{
int x, y;
node(){}
node(int x, int y):x(x), y(y){}
};
struct hashtable
{
int x, y;
hashtable * next;
hashtable()
{
next = ;
}
};
hashtable * Hash[mod];
void Hash_Insert(node a)
{
int key = (a.x * a.x + a.y * a.y) % mod;
if(!Hash[key])
{
hashtable * p = new hashtable;
p->x = a.x;
p->y = a.y;
Hash[key] = p;
}
else
{
hashtable *p = Hash[key];
while(p->next)p=p->next;
hashtable* temp = new hashtable;
temp->x = a.x;
temp->y = a.y;
p->next = temp;
}
}
bool Find(node a)
{
int key = (a.x * a.x + a.y * a.y) % mod;
if(!Hash[key])return false;
else
{
hashtable * temp = Hash[key];
while(temp)
{
if(temp->x == a.x && temp->y == a.y)
return true;
temp = temp->next;
}
}
return false;
}
node a[maxn]; node Rotate(node a, node b)//点b绕着点a逆时针旋转90度的坐标
{
int x = (b.x - a.x) * - (b.y - a.y) * + a.x;
int y = (b.x - a.x) * + (b.y - a.y) * + a.y;
return node(x, y);
} int main()
{
int n;
while(scanf("%d", &n) != EOF && n)
{
memset(Hash, , sizeof(Hash));
for(int i = ; i <= n; i++)
{
scanf("%d%d", &a[i].x, &a[i].y);
Hash_Insert(a[i]);
}
int ans = ;
node x, y;
for(int i = ; i <= n; i++)
{
for(int j = i + ; j <= n; j++)
{
x = Rotate(a[i], a[j]);
y = Rotate(x, a[i]);
if(Find(x) && Find(y))ans++;
//cout<<i<<" "<<j<<" "<<x.x<<" "<<x.y<<" "<<y.x<<" "<<y.y<<endl;
x = Rotate(a[j], a[i]);
y = Rotate(x, a[j]);
if(Find(x) && Find(y))ans++;
}
}
printf("%d\n", ans / );
}
return ;
}

最新文章

  1. Git配置姓名和邮箱问题
  2. 如何给开源的DUILib支持Accessibility
  3. 我读过的最好的epoll讲解--转自”知乎“
  4. 收到远程通知,怎么区分是点击通知栏提醒进去的还是在foreground收到的通知?
  5. jquery ajax清除缓存的方法
  6. PV3D学习笔记-导入DAE模型
  7. Javascript 电子时钟源码
  8. MySQL基础之第11章 插入、更新与删除数据
  9. Centos7源码安装mysql及读写分离,互为主从
  10. 【三支火把】---C语言const用法总结
  11. 关于自定义UICollectionViewLayout的一点个人理解&lt;一&gt;
  12. Android 之窗口小部件高级篇--App Widget 之 RemoteViews - 跨到对岸去
  13. 学习ExtJS的grid布局
  14. JavaScript之iframe页面间通信
  15. SQL Server没有足够的内存继续执行程序 (mscorlib)的解决办法
  16. (cvpr2019) The Degradation Model and Solution of DPSR
  17. 代码规范mark一下
  18. jexus手动跨域设置
  19. C# 指定ip段生成ip地址
  20. JS案例 - 可自动伸缩高度的textarea文本框

热门文章

  1. XtraFinder
  2. python3+selenium获取列表某一列的值
  3. js Form表单转json格式,及后台接收(多种方法)
  4. 并行执行hive脚本
  5. C++标准库vector及迭代器
  6. Angular JS ng-model对&lt;select&gt;标签无效的情况
  7. getResourceAsStream小结
  8. java多线程(三)
  9. Android NDK开发 图片处理(五)
  10. linux 安装dubbo+zookeeper