您的位置:首页 > 其它

POJ 2002 Squares

2013-08-15 15:36 411 查看
  给出N个点,判断可以组成多少个正方形。最后输出正方形的个数。

  思路:枚举每两个点,计算出另外的两个点,若另外两点存在则正方形存在。

  这样得到的结果是最终结果的二倍,因为每一个正方形均累加了两次。

  另外两点的计算方法:

  设AC和BD的交点O的坐标为(X0,Y0),

  则有 X0 = (X1+X3)/2 , Y 0 = (Y1+Y3)/2;

  从图上可以看出:

  X2-X0 = Y3-Y0, Y2-Y0 = X0-X3;

  将上述四式合并得:

  X2 = (X1+X3+Y3-Y1)/2;

  Y2 = (Y1+Y3+X1-X3)/2;

  同理可得:

  X4 = (X1+X3-Y3+Y1)/2;

  Y4 = (Y1+Y3-X1+X3)/2;

  

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>

using namespace std;

struct P
{
int x,y;
}point[1010];

bool cmp(P p1,P p2)
{
if(p1.x == p2.x)
return p1.y < p2.y;
return p1.x < p2.x;
}

bool check(P p,int n)
{
int first = 0,mid,last = n-1;
p.x >>= 1;
p.y >>= 1;
while(1)
{
mid = (first+last)/2;
if(point[mid].x == p.x && point[mid].y == p.y)
return true;
if(point[mid].x < p.x || (point[mid].x == p.x && point[mid].y < p.y))
{
first = mid+1;
}
else
{
last = mid-1;
}
if(last < first)
return false;
}
}

int main()
{
int ans;
int n,i,j;
P t1,t2,p1,p2;
while(scanf("%d",&n) && n)
{
ans = 0;
for(i = 0;i < n; i++)
scanf("%d %d",&point[i].x,&point[i].y);
sort(point,point+n,cmp);

for(i = 0;i < n; i++)
{
for(j = i+1;j < n; j++)
{
p1 = point[i];
p2 = point[j];
t1.x = point[i].x+point[j].x+point[j].y-point[i].y;
t1.y = point[i].y+point[j].y+point[i].x-point[j].x;
t2.x = point[i].x+point[j].x-point[j].y+point[i].y;
t2.y = point[i].y+point[j].y+point[j].x-point[i].x;
if((t1.x&1) == 0 && (t1.y&1) == 0 && (t2.x&1) == 0 && (t2.y&1) == 0 && check(t1,n) && check(t2,n))
{
++ans;
}
}
}
printf("%d\n",(ans>>1));
}
return 0;
}


View Code

  

  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: