这题用的是矩形切割:每加入一个新矩形就用这个矩形去切割被它覆盖的矩形,然后把切割后新出现的矩形加入到队列中。但如果不把被切割的矩形删掉的话就就会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.