[计算几何]点集中的点能组成多少个正方形

http://acm.pku.edu.cn/JudgeOnline/problem?id=2002

http://acm.pku.edu.cn/JudgeOnline/problem?id=3432

枚举正方形一条对角线线上的2个点,很容易求出另外2个点,然后要检查另外2个点是否坐标都是整数,如果都是,然后看这2个点是否在点集中,要快速的判断一个点是否在点集中,可以先把点排序,然后二分查找,或者对点的坐标进行hash处理(速度更快)。

注意点:

在检查一个浮点数(x)是否是整数时,不能这样:

int x1=(int)x;

if(fabs(x-x1)<eps) //则是整数

因为对浮点数强制类型转换的结果是丢掉小数位

比如int(1.99999999999999999)=1

而1.999999999999999可以看做就是整数2,因此在对强制类型转换得到整数a后,要分别对a和a+1与原浮点数进行做差判断!

Hash版本:

#include <cstdio>
#include 
<cmath>

const int maxn=2002;
const double eps=1.0e-6;
const int PRIME=9991;

struct Point {
    
int x,y;
};

struct HASH {
    
int cnt;
    
int next;
} hash[
50000];
int hash1;

Point points[maxn];

inline 
void Rotate(double x,double y,Point P,double &x1,double &y1) {
    
double vx=P.x-x,vy=P.y-y;
    x1
=x;y1=y;
    x1
-=vy;
    y1
+=vx;
}

bool getsquare(Point p1,Point p2,Point &p3,Point &p4) {
    
double midx=(p1.x+p2.x)/2.0;
    
double midy=(p1.y+p2.y)/2.0;
    
double p3x,p3y,p4x,p4y;
    Rotate(midx,midy,p1,p3x,p3y);
    Rotate(midx,midy,p2,p4x,p4y);
    p3.x
=int(p3x);
    p3.y
=int(p3y);
    p4.x
=int(p4x);
    p4.y
=int(p4y);
    
bool tag=false;
    
if(fabs(p3.x+1-p3x)<eps) {p3.x++;tag=true;}
    
if(fabs(p3x-p3.x)<eps) tag=true;
    
if(!tag) return false;
    tag
=false;
    
if(fabs(p3.y+1-p3y)<eps) {p3.y++;tag=true;}
    
if(fabs(p3y-p3.y)<eps) tag=true;
    
if(!tag) return false;
    tag
=false;
    
if(fabs(p4.x+1-p4x)<eps) {p4.x++;tag=true;}
    
if(fabs(p4x-p4.x)<eps) tag=true;
    
if(!tag) return false;
    tag
=false;
    
if(fabs(p4.y+1-p4y)<eps) {p4.y++;tag=true;}
    
if(fabs(p4y-p4.y)<eps) tag=true;
    
if(!tag) return false;
    
return true;
}

int Hash(int n) {
    
int i=n%PRIME;
    
while(hash[i].next!=-1) {
        
if(hash[hash[i].next].cnt==n) return 1;
        
else if(hash[hash[i].next].cnt>n) break;
        i
=hash[i].next;
    }
    hash[hash1].cnt
=n;
    hash[hash1].next
=hash[i].next;
    hash[i].next
=hash1;
    hash1
++;
    
return 0;
}

int Hash2(int n) {
    
int i=n%PRIME;
    
while(hash[i].next!=-1) {
        
if(hash[hash[i].next].cnt==n) return 1;
        
else if(hash[hash[i].next].cnt>n) return 0;
        i
=hash[i].next;
    }
    
return 0;
}
    
int main() {
    
int n,x,y;
    Point p1,p2;
    scanf(
"%d",&n);
        
for(int i=0;i<PRIME;i++) hash[i].next=-1;
        hash1
=PRIME;
        
for(int i=0;i<n;i++) {
            scanf(
"%d %d",&points[i].x,&points[i].y);
            Hash((points[i].x
+100000)*100000+points[i].y+100000);
        }
        
int cnt=0;
        
for(int i=0;i<n;i++) {
            
for(int j=i+1;j<n;j++) {
                
bool ok=getsquare(points[i],points[j],p1,p2);
                
if(!ok) continue;
                
if(Hash2((p1.x+100000)*100000+p1.y+100000)==0continue;
                
if(Hash2((p2.x+100000)*100000+p2.y+100000)==0continue;
                cnt
++;
            }
        }
        printf(
"%d\n",cnt/2);
    
return 0;
}

           

排序+二分查找版本:

#include <cstdio>
#include 
<cmath>
#include 
<algorithm>
using namespace std;

const int maxn=2002;
const double eps=1.0e-6;

struct Point {
    
int x,y;
};

bool operator<(const Point& t1,const Point& t2) {
    
if(t1.x!=t2.x) return t1.x<t2.x;
    
if(t1.y!=t2.y) return t1.y<t2.y;
    
return false;
}

Point points[maxn];

inline 
void Rotate(double x,double y,Point P,double &x1,double &y1) {
    
double vx=P.x-x,vy=P.y-y;
    x1
=x;y1=y;
    x1
-=vy;
    y1
+=vx;
}

bool getsquare(Point p1,Point p2,Point &p3,Point &p4) {
    
double midx=(p1.x+p2.x)/2.0;
    
double midy=(p1.y+p2.y)/2.0;
    
double p3x,p3y,p4x,p4y;
    Rotate(midx,midy,p1,p3x,p3y);
    Rotate(midx,midy,p2,p4x,p4y);
    p3.x
=int(p3x);
    p3.y
=int(p3y);
    p4.x
=int(p4x);
    p4.y
=int(p4y);
    
bool tag=false;
    
if(fabs(p3.x+1-p3x)<eps) {p3.x++;tag=true;}
    
if(fabs(p3x-p3.x)<eps) tag=true;
    
if(!tag) return false;
    tag
=false;
    
if(fabs(p3.y+1-p3y)<eps) {p3.y++;tag=true;}
    
if(fabs(p3y-p3.y)<eps) tag=true;
    
if(!tag) return false;
    tag
=false;
    
if(fabs(p4.x+1-p4x)<eps) {p4.x++;tag=true;}
    
if(fabs(p4x-p4.x)<eps) tag=true;
    
if(!tag) return false;
    tag
=false;
    
if(fabs(p4.y+1-p4y)<eps) {p4.y++;tag=true;}
    
if(fabs(p4y-p4.y)<eps) tag=true;
    
if(!tag) return false;
    
return true;
}
    
int main() {
    
int n,x,y;
    Point p1,p2;
    
while(scanf("%d",&n)!=EOF&&n) {
        
for(int i=0;i<n;i++) {
            scanf(
"%d %d",&points[i].x,&points[i].y);
        }
        sort(points,points
+n);
        
int cnt=0;
        
for(int i=0;i<n;i++) {
            
for(int j=i+1;j<n;j++) {
                
bool ok=getsquare(points[i],points[j],p1,p2);
                
if(ok)
                    
if(binary_search(points,points+n,p1) && binary_search(points,points+n,p2)) 
                        cnt
++;
            }
        }
        printf(
"%d\n",cnt/2);
    }
    
return 0;
}

           

posted on 2008-09-17 00:33  woodfish  阅读(675)  评论(0编辑  收藏  举报

导航