poj2002 (极简单数学/几何+hash)

链接:http://poj.org/problem?id=2002

Squares

Time Limit: 3500MS   Memory Limit: 65536K
Total Submissions: 21720   Accepted: 8321

Description

A square is a 4-sided polygon whose sides have equal length and adjacent sides form 90-degree angles. It is also a polygon such that rotating about its centre by 90 degrees gives the same polygon. It is not the only polygon with the latter property, however, as a regular octagon also has this property.

So we all know what a square looks like, but can we find all possible squares that can be formed from a set of stars in a night sky? To make the problem easier, we will assume that the night sky is a 2-dimensional plane, and each star is specified by its x and y coordinates.

Input

The input consists of a number of test cases. Each test case starts with the integer n (1 <= n <= 1000) indicating the number of points to follow. Each of the next n lines specify the x and y coordinates (two integers) of each point. You may assume that the points are distinct and the magnitudes of the coordinates are less than 20000. The input is terminated when n = 0.

Output

For each test case, print on a line the number of squares one can form from the given stars.

Sample Input

4
1 0
0 1
1 1
0 0
9
0 0
1 0
2 0
0 2
1 2
2 2
0 1
1 1
2 1
4
-2 5
3 7
0 0
5 2
0

Sample Output

1
6
1

先留上几个坑:

①据说有二分做法,占坑待更;

②一开始用的向量,T了。。。回头把vector换成数组,然后优化一下常数,占坑待更

题目大意:

  平面内有n(1<=n<=1000)个点,给定点的坐标Xi,Yi,求一共可以组成多少个正方形

  分析:根据几何关系,由其中两点a,b确定另外两点m,n,看m,n是否存在,确定两点的时间复杂度是O(n2),查找的时间复杂度是O(logN),总体是O(2n2logn)数据范围在1000内,可以接受

  一开始用的向量匹配,确定n2条向量,然后确定令一条向量的起点和大小,方向(平行),进行向量匹配,然后T了(坑①)(这里还有个(错误的)思路,两个向量垂直,不过这样只能确定三个点,就没再想了)然后就根据两个点匹配另外两个点,900+MS,A掉了(看来常数写的不行)

上代码:

 1     #include<iostream>
 2     #include<cstdio>
 3     #include<queue>
 4     #include<cstdio>
 5     #include<cstring>
 6     #include<cstdlib>
 7     #define mem(a,b) memset(a,b,sizeof(a))
 8     using namespace std;
 9
10     const int mod=100007;
11     const int maxn=120009;
12     struct node
13     {
14         int  x,y,next;
15     }edge[maxn];
16     int cnt;
17     int ans,head[maxn];
18     int xi[1111],yi[1111];
19     inline int read()
20     {
21         char ch = getchar(); int x = 0, f = 1;
22         while(ch < ‘0‘ || ch > ‘9‘) {if(ch == ‘-‘) f = -1; ch = getchar();}
23         while(‘0‘ <= ch && ch <= ‘9‘) {x = x * 10 + ch - ‘0‘; ch = getchar();}
24         return x * f;
25     }
26     void out(int a)  //代替printf,速度更快,俗称输出挂
27     {
28         if(a > 9)
29         {
30             out(a/10);
31         }
32         putchar(a%10 + ‘0‘);
33     }
34     void ins(int x,int y,int h)
35     {
36         h%=mod;
37         edge[cnt].x=x;
38         edge[cnt].y=y;
39         edge[cnt].next=head[h];
40         head[h]=cnt++;
41     }
42     inline bool cmp(node a,node b)
43     {
44         if(a.x==b.x&&a.y==b.y) return 1;
45         return 0;
46     }
47     bool search(node a,int h)
48     {
49         h%=mod;
50         //printf("search:\n");
51         for(int i=head[h];i!=-1;i=edge[i].next)
52         {
53             //"%d %d   %d %d     %d %d     %d %d     %d %d     %d %d\n",xi[i],yi[i],xi[j],yi[j],a.x,a.y,b.x,b.y,c.x,c.y,d.x,d.y);
54             if(cmp(edge[i],a)) return 1;
55         }
56         return 0;
57     }
58     void init()
59     {
60         mem(edge,0);
61         mem(head,-1);
62         mem(xi,0);
63         mem(yi,0);
64         cnt=0;
65         ans=0;
66     }
67     int main()
68     {
69         int n;
70         while(scanf("%d",&n)&&n)
71         {
72             init();
73             for(int i=1;i<=n;i++)
74             {
75                 xi[i]=read();yi[i]=read();
76                 ins(xi[i],yi[i],abs(xi[i]*1000+yi[i]));
77             }
78             for(int i=1;i<=n;i++)
79             {
80                 for(int j=i+1;j<=n;j++)
81                 {
82                     int dty=yi[j]-yi[i],dtx=xi[j]-xi[i];
83                     node a,b,c,d;
84                     a.x=xi[i]+dty;a.y=yi[i]-dtx;
85                     b.x=xi[j]+dty;b.y=yi[j]-dtx;
86                     c.x=xi[i]-dty;c.y=yi[i]+dtx;
87                     d.x=xi[j]-dty;d.y=yi[j]+dtx;
88                     int ha=abs(a.x*1000+a.y),hb=abs(b.x*1000+b.y),
89                         hc=abs(c.x*1000+c.y),hd=abs(d.x*1000+d.y);
90                     //printf("%d %d   %d %d     %d %d     %d %d     %d %d     %d %d\n",xi[i],yi[i],xi[j],yi[j],a.x,a.y,b.x,b.y,c.x,c.y,d.x,d.y);
91                     if(search(a,ha)&&search(b,hb)) {ans++;}
92                     if(search(c,hc)&&search(d,hd)) {ans++;}
93                 }
94             }
95             out(ans/4);putchar(‘\n‘);
96         }
97     }

原文地址:https://www.cnblogs.com/codeoosacm/p/9822855.html

时间: 2024-08-26 17:34:46

poj2002 (极简单数学/几何+hash)的相关文章

hdu 1577 WisKey的眼神 (数学几何)

WisKey的眼神 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2059    Accepted Submission(s): 625 Problem Description WisKey的眼镜有500多度,所以眼神不大好,而且他有个习惯,就是走路喜欢看着地(不是为了拣钱哦^_^),所以大家下次碰见他的时候最好主动打下招呼,呵呵.但是

hdu 2200 Eddy&#39;s AC难题(简单数学。。)

题意: N个人,每个人AC的题数都不一样. Eddy想从中选出一部分人(或者全部)分成两组.必须满足第一组中的最小AC数大于第二组中的最大AC数. 问共有多少种不同的选择方案. 思路: 简单数学.. 代码: ll C(int n,int x){ ll ans=1; rep(i,1,x){ ans = ans*(n+1-i)/i; } return ans; } int main(){ int n; while(cin>>n){ ll ans = 0; rep(i,2,n){ ans += (C

hdu 1115 Lifting the Stone (数学几何)

Lifting the Stone Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 5203    Accepted Submission(s): 2155 Problem Description There are many secret openings in the floor which are covered by a big

最简单的一致性Hash算法实现

import java.util.Collection;import java.util.SortedMap;import java.util.TreeMap; public class ConsistentHash<T> { private final HashFunction hashFunction; private final int numberOfReplicas; private final SortedMap<Integer, T> circle = new Tre

编译器--简单数学表达式计算器

做了一个能够计算简单数学表达式值的小计算器,算不上是编译器,但用到了编译器的知识.最近在看一些编译器的东西,所以动手写这个最简单的计算器,既是对那些抽象的编译器知识有个形象的认识,也为后面添加复杂的东西--语句打下基础.此计算器是以<编译原理与实践>中实现的tiny编译器为参考写的,tiny是一个值得去研究的编译器,可以说是麻雀虽小,五脏俱全.从词法分析到代码生成都有,并且代码非常清晰易懂.我觉得想要了解编译器,可以从tiny入手,去将它跑起来并分析.废话不多说,开始记录这个小计算器. 先说下

利用单片机实现极简单的测温电路(转)

源:http://www.sinochip.net/TechSheet/67.htm 参考:http://www.docin.com/p-281643435.html 利用单片机实现极简单的测温电路 单片机在电子产品中的应用已经越来越广泛,在很多的电子产品中也用到了温度检测和温度控制,但那些温度检测与控制电路通常较复杂,成本也高,本文提供了一种低成本的利用单片机多余I/O口实现的温度检测电路,该电路非常简单,且易于实现,并且适用于几乎所有类型的单片机.其电路如下图所示: 图中: P1.0.P1.

HDU 1018 Big Number (简单数学)

Big Number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 25649    Accepted Submission(s): 11635 Problem Description In many applications very large integers numbers are required. Some of these

【龙书笔记】用Python实现一个简单数学表达式从中缀到后缀语法的翻译器(采用递归下降分析法)

上篇笔记介绍了语法分析相关的一些基础概念,本篇笔记根据龙书第2.5节的内容实现一个针对简单表达式的后缀式语法翻译器Demo. 备注:原书中的demo是java实例,我给出的将是逻辑一致的Python版本的实现. 在简单后缀翻译器代码实现之前,还需要介绍几个基本概念. 1. 自顶向下分析法(top-down parsing) 顾名思义,top-down分析法的思路是推导产生式时,以产生式开始符号作为root节点,从上至下依次构建其子节点,最终构造出语法分析树.在具体实现时,它会把输入字符串从左到右

SGU - 123 - The sum (简单数学!)

SGU - 123 The sum Time Limit: 250MS   Memory Limit: 4096KB   64bit IO Format: %I64d & %I64u Submit Status Description Here is your second problem, keep calm and solve it . Nacci sequence of numbers is known to all : F1 = 1; F2 = 1; Fn+1 = Fn + Fn-1,