惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
S
Schneier on Security
A
Arctic Wolf
Scott Helme
Scott Helme
S
Securelist
Schneier on Security
Schneier on Security
W
WeLiveSecurity
Attack and Defense Labs
Attack and Defense Labs
Security Latest
Security Latest
Project Zero
Project Zero
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Know Your Adversary
Know Your Adversary
P
Palo Alto Networks Blog
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Google DeepMind News
Google DeepMind News
P
Proofpoint News Feed
C
Check Point Blog
F
Full Disclosure
Stack Overflow Blog
Stack Overflow Blog
H
Hacker News: Front Page
T
The Blog of Author Tim Ferriss
TaoSecurity Blog
TaoSecurity Blog
Vercel News
Vercel News
A
About on SuperTechFans
N
News and Events Feed by Topic
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
The GitHub Blog
The GitHub Blog
S
Security Affairs
Y
Y Combinator Blog
T
The Exploit Database - CXSecurity.com
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Forbes - Security
Forbes - Security
IT之家
IT之家
WordPress大学
WordPress大学
Last Week in AI
Last Week in AI
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
F
Fortinet All Blogs
N
Netflix TechBlog - Medium
The Register - Security
The Register - Security
Jina AI
Jina AI
云风的 BLOG
云风的 BLOG
T
Tailwind CSS Blog
K
Kaspersky official blog
Hacker News: Ask HN
Hacker News: Ask HN
C
Cisco Blogs
MyScale Blog
MyScale Blog
博客园 - 【当耐特】
T
Threat Research - Cisco Blogs
D
Docker
G
GRAHAM CLULEY

博客园 - woodfish

偏序集的Dilworth定理 XJOJ历经2个月终于完成啦~~ fork()调用的一个趣题 实现google那种输入框提示的功能 POJ 3691 安徽第二题 有限状态自动机+DP 哈尔滨赛区网络预选赛总结 [计算几何]POJ 1375 点对圆的切线+线段重叠 [计算几何]POJ 1556 判断线段相交+Dijkstra [计算几何] POJ 1873 暴力+凸包 [计算几何]POJ 1266 三角形的外接圆 圆的参数方程 POJ 1026 置换群 [计算几何]POJ 1031 计算点对多边形的偏转角度 [计算几何]POJ2079 求点集中面积最大的三角形 [计算几何]POJ3608 求2个不相交凸包的最短距离 [计算几何]凸包的旋转卡壳算法 C++禁止一个类被继承的技术 C与汇编的接口技术 计算位数的3种方法 避免使用条件分支
[计算几何]点集中的点能组成多少个正方形
woodfish · 2008-09-17 · via 博客园 - woodfish

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;
}