[题目来源]:POJ2002
[关键字]:Hash (二分)
[题目大意]:给出n个点,求它们共组成了多少个正方形。
//===========================================================================================================
[分析]:因为是正方形所以只要枚举任意两点即可求出另外两点的坐标,数学问题在此不再诉述可以自己推一推。现在的任务就是判断求出的可以构成正方形的两点是否存在,先排序这样枚举时可以节省时间。至于查找有两种方法:1、hash每一点坐标值(x^2+y^2 mod 素数),然后查找。2、二分查找。hash过了,二分总是超时........
[代码]:
1 program Project1;
2 type
3 rec = record
4 x, y: longint;
5 end;
6 var
7 h: array[0..20000,0..20] of rec;
8 a: array[0..2000] of rec;
9 num: array[0..20000] of longint;
10 n, ans: longint;
11
12 procedure qs(l, r: longint);
13 var
14 i, j, midx, midy: longint;
15 t: rec;
16 begin
17 i := l;
18 j := r;
19 midx := a[(l+r) shr 1].x;
20 midy := a[(l+r) shr 1].y;
21 repeat
22 while (a[i].x < midx) or ((a[i].x = midx) and (a[i].y < midy)) do inc(i);
23 while (a[j].x > midx) or ((a[j].x = midx) and (a[j].y > midy)) do dec(j);
24 if i <= j then
25 begin
26 t := a[i];
27 a[i] := a[j];
28 a[j] := t;
29 inc(i);
30 dec(j);
31 end;
32 until i > j;
33 if l < j then qs(l,j);
34 if i < r then qs(i,r);
35 end;
36
37 function hash(x, y: longint):longint;
38 begin
39 hash := (x*x+y*y) mod 15988;
40 end;
41
42 procedure init;
43 var
44 i, k: longint;
45 begin
46 readln(n);
47 if n = 0 then halt;
48 fillchar(num,sizeof(num),0);
49 fillchar(h,sizeof(h),0);
50 for i := 1 to n do
51 begin
52 readln(a[i].x,a[i].y);
53 k := hash(a[i].x,a[i].y);
54 inc(num[k]);
55 h[k,num[k]].x := a[i].x;
56 h[k,num[k]].y := a[i].y;
57 end;
58 qs(1,n);
59 end;
60
61 function find(x, y: longint):boolean;
62 var
63 k, i: longint;
64 begin
65 k := hash(x,y);
66 for i := 1 to num[k] do
67 if (h[k,i].x = x) and (h[k,i].y = y) then exit(true);
68 exit(false);
69 end;
70
71 procedure work;
72 var
73 i, j, x1, y1, x2, y2, tempx, tempy: longint;
74 f1, f2: boolean;
75 begin
76 ans := 0;
77 for i := 1 to n do
78 for j := i+1 to n do
79 begin
80 tempx := a[j].x-a[i].x;
81 tempy := a[j].y-a[i].y;
82 x1 := a[i].x-tempy;
83 y1 := a[i].y+tempx;
84 x2 := a[j].x-tempy;
85 y2 := a[j].y+tempx;
86 //writeln(a[i].x,' ',a[i].y,' ',a[j].x,' ',a[j].y,' ',x1,' ',y1,' ',x2,' ',y2);
87 f1 := find(x1,y1);
88 f2 := find(x2,y2);
89 if f1 and f2 then inc(ans);
90 //writeln(ans);
91 end;
92 ans := ans shr 1;
93 writeln(ans);
94 end;
95
96 begin
97 while 1 = 1 do
98 begin
99 init;
100 work;
101 end;
102 end.