USACO 3.1.4 RECT1

http://hi.baidu.com/raulliubo/blog/item/416faa7ec7321d3c0dd7da57.html

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.

posted @ 2009-01-04 12:21  jesonpeng  阅读(240)  评论(0编辑  收藏  举报