您的位置:首页 > 其它

POJ 2002--Squares

2014-07-26 18:07 483 查看
题目要求四点能组成正方形的个数,若直接枚举四点,会TLE。可以根据正方形公式,题目有提示,正方形旋转90度与原图形重合。

我们可以枚举对角线,只有5*10^5个,根据对角线经过中点旋转,来得到另外的两点。可以形象地理解已知A(x1,y1),C(x2,y2)为正方形对角线,经过旋转AB边在x,y轴上的投影长度会互换调。
即是假设另两点为B(x3,y3),D(x4,y4),正方形ABCD,有:

x3+x4 = x1+x2;
y3+y4 = y1+y2;(对角线中点重叠)
x4-x3 = y1-y2;y4-y3 = x2-x1;(旋转之后边的投影长度互换),解以上方程可得BD。

优化:因为B,D坐标必须为整数,所以以上枚举边时所得式必须得出整除结果,因为我们是从点枚举边,所以j = i+1,即每条边只枚举一次。又因为对角线有两条,在枚举到另一条对角线,最好是不用再判断了,最开始使用了map将点和第几点的i,j对应起来,map比较慢。然后考虑到就算枚举了另一条对角线,也只增加一个正方形,所以最后结果除以2.
Hash函数一直用的不好,Hash保存已给点的坐标,key值为坐标经过变换而得,因为坐标x或y属于(-20000,20000),所以坐标对总共有1.6*10^9个,需要散列处理,经过试验,选择500000左右的素数是比较理想的。 px前面的加权有坐标上限确定。

hash:
#include<cstdio>
#include<cstring>
#include<map>
using namespace std;
#define maxN 499927
#define maxM 1001
#define maxL 11

struct node
{
int px,py;
node* next;
}* hashTab[maxN];
struct _node
{
int px,py;
}point[maxM];

bool check(int x,int y)
{
int slot = (x*maxL+y)%maxN;
node* nowNode;
for(nowNode = hashTab[slot];nowNode != NULL;nowNode = nowNode->next)
{
if(nowNode->px == x&&nowNode->py == y)
return true;
}
return false;
}

int main()
{
int N;
int i,j;
int slot;
int squareNum;
int x1,x2,x3,x4,y1,y2,y3,y4;
node* tmpNode;
int nodeNum1,nodeNum2;
while(scanf("%d",&N))
{
if(!N)
return 0;
squareNum = 0;
memset(hashTab,0,sizeof(hashTab));
for(i = 0;i < N;i++)
{
scanf("%d%d",&point[i].px,&point[i].py);
point[i].px += 20000;
point[i].py += 20000;
tmpNode = new node;
tmpNode->px = point[i].px;
tmpNode->py = point[i].py;
slot = (point[i].px*maxL+point[i].py)%maxN;
tmpNode->next = hashTab[slot];
hashTab[slot] = tmpNode;
}
for(i = 0;i < N;i++)
{
x1 = point[i].px;
y1 = point[i].py;
for(j = i+1;j < N;j++)
{
x2 = point[j].px;
y2 = point[j].py;
if((x1+x2+y2-y1)%2 == 0)
x3 = (x1+x2+y2-y1)/2;
else
continue;
if((x1+x2+y1-y2)%2 == 0)
x4 = (x1+x2+y1-y2)/2;
else
continue;
if((y1+y2+x1-x2)%2 == 0)
y3 = (y1+y2+x1-x2)/2;
else
continue;
if((y1+y2+x2-x1)%2 == 0)
y4 = (y1+y2+x2-x1)/2;
else
continue;
if(check(x3,y3)&&check(x4,y4))
{
squareNum++;
}
}
}
printf("%d\n",squareNum/2);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: