您的位置:首页 > 其它

[POJ2002 Squares]

2011-10-18 18:46 393 查看
[题目来源]:POJ2002

[关键字]:Hash (二分)

[题目大意]:给出n个点,求它们共组成了多少个正方形。

//===========================================================================================================

[分析]:因为是正方形所以只要枚举任意两点即可求出另外两点的坐标,数学问题在此不再诉述可以自己推一推。现在的任务就是判断求出的可以构成正方形的两点是否存在,先排序这样枚举时可以节省时间。至于查找有两种方法:1、hash每一点坐标值(x^2+y^2 mod 素数),然后查找。2、二分查找。hash过了,二分总是超时........

[代码]:

View Code

program Project1;
type
rec = record
x, y: longint;
end;
var
h: array[0..20000,0..20] of rec;
a: array[0..2000] of rec;
num: array[0..20000] of longint;
n, ans: longint;

procedure qs(l, r: longint);
var
i, j, midx, midy: longint;
t: rec;
begin
i := l;
j := r;
midx := a[(l+r) shr 1].x;
midy := a[(l+r) shr 1].y;
repeat
while (a[i].x < midx) or ((a[i].x = midx) and (a[i].y < midy)) do inc(i);
while (a[j].x > midx) or ((a[j].x = midx) and (a[j].y > midy)) do dec(j);
if i <= j then
begin
t := a[i];
a[i] := a[j];
a[j] := t;
inc(i);
dec(j);
end;
until i > j;
if l < j then qs(l,j);
if i < r then qs(i,r);
end;

function hash(x, y: longint):longint;
begin
hash := (x*x+y*y) mod 15988;
end;

procedure init;
var
i, k: longint;
begin
readln(n);
if n = 0 then halt;
fillchar(num,sizeof(num),0);
fillchar(h,sizeof(h),0);
for i := 1 to n do
begin
readln(a[i].x,a[i].y);
k := hash(a[i].x,a[i].y);
inc(num[k]);
h[k,num[k]].x := a[i].x;
h[k,num[k]].y := a[i].y;
end;
qs(1,n);
end;

function find(x, y: longint):boolean;
var
k, i: longint;
begin
k := hash(x,y);
for i := 1 to num[k] do
if (h[k,i].x = x) and (h[k,i].y = y) then exit(true);
exit(false);
end;

procedure work;
var
i, j, x1, y1, x2, y2, tempx, tempy: longint;
f1, f2: boolean;
begin
ans := 0;
for i := 1 to n do
for j := i+1 to n do
begin
tempx := a[j].x-a[i].x;
tempy := a[j].y-a[i].y;
x1 := a[i].x-tempy;
y1 := a[i].y+tempx;
x2 := a[j].x-tempy;
y2 := a[j].y+tempx;
//writeln(a[i].x,' ',a[i].y,' ',a[j].x,' ',a[j].y,' ',x1,' ',y1,' ',x2,' ',y2);
f1 := find(x1,y1);
f2 := find(x2,y2);
if f1 and f2 then inc(ans);
//writeln(ans);
end;
ans := ans shr 1;
writeln(ans);
end;

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