本题题意很容易理解,苦于数据量比较大,并且人家有提示如果存储所有数据的话超内存。本题不仅在时间上很苛刻,在空间上的障碍也是较大的制约。所以,在这里我们可以借鉴题意中的表示方法,仅记录一个色块左下角坐标和右上角坐标,也就是离散化,然后倒序染色,以逆序来进行放置,即n to 1。逆序的好处在于放置一个矩形后,俯视看到的就是最终俯视该矩形应该看到的。因为挡着它的矩形在之前已经放置好了,所以可直接统计,可用递归。
#include<cstdio>
#include<iostream>
#include<string.h>
using namespace std;
int A,B,n;
int llx[1001],lly[1001],rrx[1001],rry[1001],col[1001];
int sum[2501];
int remain(int lx,int ly,int rx,int ry,int pre)
{
if(pre>n) return ((rx-lx)*(ry-ly));
if(rx==lx||ry==ly) return 0;
if(lx>=rrx[pre]||rx<=llx[pre]||ry<=lly[pre]||ly>=rry[pre])
return remain(lx,ly,rx,ry,pre+1);
int x[4],y[4];
x[0]=lx,y[0]=ly;
x[1]=max(lx,llx[pre]),y[1]=max(ly,lly[pre]);
x[2]=min(rx,rrx[pre]),y[2]=min(ry,rry[pre]);
x[3]=rx,y[3]=ry;
int sum=0;
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
{
if(i!=1||j!=1)
sum+=remain(x[i],y[j],x[i+1],y[j+1],pre+1);
}
return sum;
}
int main()
{
freopen("rect1.in","r",stdin);
freopen("rect1.out","w",stdout);
cin>>A>>B>>n;
llx[0] = 0; lly[0] = 0;
rrx[0] = A; rry[0] = B;
col[0]=1;
for(int i=1;i<=n;i++)
cin>>llx[i]>>lly[i]>>rrx[i]>>rry[i]>>col[i];
memset(sum,0,sizeof(sum));
for(int i=n;i>=0;i--)
sum[col[i]]+=remain(llx[i],lly[i],rrx[i],rry[i],i+1);
for(int i=1;i<=2500;i++)
if(sum[i]>0)
cout<<i<<" "<<sum[i]<<endl;
return 0;
}