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

Posted codeoosacm

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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:
");
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
",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
",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(
);
96         }
97     }
View Code

 



以上是关于poj2002 (极简单数学/几何+hash)的主要内容,如果未能解决你的问题,请参考以下文章

POJ 2002 Squares 数学 + 必须hash

POJ 2002 二分 计算几何

POJ 2002 统计正方形 HASH

[poj2002]Squares_hash

POJ 1113 Wall 凸包 裸

POJ 1113 Wall(思维 计算几何 数学)