USACO 6.2.3 shaping regions 矩形切割

这题用的是矩形切割:每加入一个新矩形就用这个矩形去切割被它覆盖的矩形,然后把切割后新出现的矩形加入到队列中。但如果不把被切割的矩形删掉的话就就会MLE,所以我一开始就每删一个矩形就从队尾拿一个元素代替要删掉的矩形的位置,结果过不了……调了一晚上啊……最后才发现这样是行不通的……然后改成了用一个数组记录空的位置,每在队列中放入一个新矩形就优先放到空的位置而不是队尾,这样就能过啦!!!

开心~~

恩再说一下判断两个矩形是否有重叠部分的方法吧:

假定矩形是用一对点表达的(minx, miny) (maxx, maxy),那么两个矩形
rect1{(minx1, miny1)(maxx1, maxy1)}
rect2{(minx2, miny2)(maxx2, maxy2)} 
相交的结果一定是个矩形,构成这个相交矩形rect{(minx, miny) (maxx, maxy)}的点对坐标是: 
minx max(minx1, minx2) 
miny max(miny1, miny2) 
maxx min(maxx1, maxx2) 
maxy min(maxy1, maxy2) 

如果两个矩形不相交,那么计算得到的点对坐标必然满足: 
( minx maxx ) 或者 ( miny maxy ) 

代码有点不优美:

{
ID: ymwbegi1
PROG: rect1
LANG: PASCAL
}

var
  j,x,y,n,f1,x1,y1,x2,y2,color,a1,i,u:longint;
  a:array[0..500000,1..5] of longint;
  f:array[1..500000] of longint;
  ans:array[1..2500] of longint;

function min(x,y:longint):longint;
begin
  if x<y then exit(x)
         else exit(y);
end;

function max(x,y:longint):longint;
begin
  if x>y then exit(x)
         else exit(y);
end;

function check(x,y:longint):boolean;
var
  x1,x2,y1,y2:longint;
begin
  if a[x,5]=0 then exit(false);
  x1:=max(a[x,1],a[y,1]);
  y1:=max(a[x,2],a[y,2]);
  x2:=min(a[x,3],a[y,3]);
  y2:=min(a[x,4],a[y,4]);
  if (x1<=x2)and(y1<=y2)
    then check:=true
    else check:=false;
end;

begin
  assign(input,'rect1.in');
  assign(output,'rect1.out');
  reset(input);
  rewrite(output);
  readln(y,x,n);
  a1:=1;
  a[1,1]:=1;
  a[1,2]:=1;
  a[1,3]:=x;
  a[1,4]:=y;
  a[1,5]:=1;
  for i:=1 to n do
  begin
    readln(x1,y1,x2,y2,color);
    inc(x1);
    inc(y1);
    a[0,1]:=y1;
    a[0,2]:=x1;
    a[0,3]:=y2;
    a[0,4]:=x2;
    a[0,5]:=color;
    x:=a1;
    for j:=1 to x do
      if check(j,0) then
      begin
        if a[j,3]>a[0,3] then
        begin
          inc(a1);
          u:=a1;
          if f1>0 then
          begin
            u:=f[f1];
            dec(f1);
            dec(a1);
          end;
          a[u,1]:=a[0,3]+1;
          a[u,2]:=a[j,2];
          a[u,3]:=a[j,3];
          a[u,4]:=a[j,4];
          a[u,5]:=a[j,5];
          a[j,3]:=a[0,3];
        end;
        if a[j,1]<a[0,1] then
        begin
          inc(a1);
          u:=a1;
          if f1>0 then
          begin
            u:=f[f1];
            dec(f1);
            dec(a1);
          end;
          a[u,1]:=a[j,1];
          a[u,2]:=a[j,2];
          a[u,3]:=a[0,1]-1;
          a[u,4]:=a[j,4];
          a[u,5]:=a[j,5];
          a[j,1]:=a[0,1];
        end;
        if a[j,2]<a[0,2] then
        begin
          inc(a1);
          u:=a1;
          if f1>0 then
          begin
            u:=f[f1];
            dec(f1);
            dec(a1);
          end;
          a[u,1]:=a[j,1];
          a[u,2]:=a[j,2];
          a[u,3]:=a[j,3];
          a[u,4]:=a[0,2]-1;
          a[u,5]:=a[j,5];
          a[j,2]:=a[0,2];
        end;
        if a[j,4]>a[0,4] then
        begin
          inc(a1);
          u:=a1;
          if f1>0 then
          begin
            u:=f[f1];
            dec(f1);
            dec(a1);
          end;
          a[u,1]:=a[j,1];
          a[u,2]:=a[0,4]+1;
          a[u,3]:=a[j,3];
          a[u,4]:=a[j,4];
          a[u,5]:=a[j,5];
          a[j,4]:=a[0,4];
        end;
        inc(f1);
        f[f1]:=j;
        a[j,5]:=0;
      end;
    inc(a1);
    a[a1]:=a[0];
  end;
  for i:=1 to a1 do
    if a[i,5]>0 then
      ans[a[i,5]]:=ans[a[i,5]]+(a[i,3]-a[i,1]+1)*(a[i,4]-a[i,2]+1);
  for i:=1 to 2500 do
    if ans[i]>0 then
      writeln(i,' ',ans[i]);
  close(input);
  close(output);
end.

你可能感兴趣的:(USACO 6.2.3 shaping regions 矩形切割)