USER: BO LIU [raulliu2]
TASK: rect1
LANG: PASCAL
Compiling...
Compile: OK
Executing...
Test 1: TEST OK [0.008 secs]
Test 2: TEST OK [0.004 secs]
Test 3: TEST OK [0.004 secs]
Test 4: TEST OK [0.008 secs]
Test 5: TEST OK [0.004 secs]
Test 6: TEST OK [0.008 secs]
Test 7: TEST OK [0.012 secs]
Test 8: TEST OK [0.012 secs]
Test 9: TEST OK [0.02 secs]
Test 10: TEST OK [0.02 secs]
Test 11: TEST OK [1.32 secs]
All tests OK.
YOUR PROGRAM ('rect1') WORKED FIRST TIME! That's fantastic
-- and a rare thing. Please accept these special automated
congratulations.
此题乃经典题也。无需讲解,做法极多,什么矩形切割,线段树,离散化。。皆可。
最近练了线段树,那就用线段树咯。
my ugly code :
{
PROG:rect1
ID:parachutes
LANG:PASCAL
}
var
area, x, x1, x2, y1, y2, co : array[1 .. 2000] of longint;
v : array[0 .. 10000] of boolean;
left, right, color : array[1 .. 80000] of longint;
a, b, n, i, j, tot : longint;
procedure buildtree;
var
i : longint;
begin
left[1] := 0; right[1] := 16384;
for i := 1 to 16384 do begin
left[i * 2] := left[i];
right[i * 2] := (left[i] + right[i]) shr 1;
left[i * 2 + 1] := right[i * 2];
right[i * 2 + 1] := right[i];
end;
end;
procedure insert(now : longint);
begin
if color[now] > 0 then exit;
if (y1[j] <= left[now]) and (y2[j] >= right[now]) and (color[now] = 0)then begin
color[now] := co[j];
exit;
end;
color[now] := -1;
if y1[j] < right[now * 2] then insert(now * 2);
if y2[j] > left[now * 2 + 1] then insert(now * 2 + 1);
end;
procedure calc(now : longint);
begin
if color[now] = 0 then exit;
if color[now] <> -1 then
inc(area[color[now]], (right[now] - left[now]) * (x[i+1] - x[i]))
else begin
calc(2 * now);
calc(2 * now + 1);
end;
color[now] := 0;
end;
begin
assign(input, 'rect1.in'); reset(input);
assign(output, 'rect1.out'); rewrite(output);
readln(a, b, n);
for i := 1 to n do begin
readln(x1[i], y1[i], x2[i], y2[i], co[i]);
v[x1[i]] := true;
v[x2[i]] := true;
end;
tot := 0;
for i := 0 to 10000 do
if v[i] then begin
inc(tot);
x[tot] := i;
end;
buildtree;
fillchar(area, sizeof(area), 0);
for i := 1 to tot - 1 do begin
for j := n downto 1 do
if (x[i] >= x1[j]) and (x[i] < x2[j]) then
insert(1);
calc(1);
end;
area[1] := a * b;
for i := 2 to 2000 do dec(area[1], area[i]);
for i := 1 to 2000 do
if area[i] <> 0 then writeln(i, ' ', area[i]);
close(input); close(output);
end.