漂浮法,顾名思义,就是一块块的往上飘。
以逆序来进行放置,即n to 1。逆序的好处在于放置一个矩形后,俯视看到的就是最终俯视该矩形应该看到的。因为挡着它的矩形在之前已经放置好了,所以可直接统计,为递归创造了条件。每放一个矩形,可以想象成将其扔入一密度很大的海水底部,海分成了n层,然后矩形开始向上浮。在上浮过程中若碰撞到其他的矩形则断裂成几个小矩形,继续上浮,直到浮出水面。于是想到用个递归来模拟上浮过程。
/*
ID: rowanha3
LANG: C++
TASK: rect1
*/
#include<iostream>
#include<cstring>
#include<queue>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<math.h>
#include<map>
#include<set>
#include<string>
using namespace std;
int n;
struct list
{
int x1,y1;
int x2,y2;
int cl;
friend bool operator < (const list &a,const list &b){
return a.cl<b.cl;
}
}rec[1100];
int ans[3001];
void dos(int x1,int y1,int x2,int y2,int color,int y)
{
if(x1>=x2||y1>=y2)return;
if(y>n)
{
ans[color]+=(x2-x1)*(y2-y1);
return;
}
struct list p;
p=rec[y];
if(y1<p.y1)dos(max(p.x1,x1),y1,max(p.x1,x2),min(p.y1,y2),color,y+1);
if(y2>p.y2)dos(min(x1,p.x2),max(y1,p.y2),min(p.x2,x2),y2,color,y+1);
if(x1<p.x1)dos(x1,min(p.y2,y1),min(p.x1,x2),min(p.y2,y2),color,y+1);
if(x2>p.x2)dos(max(p.x2,x1),max(p.y1,y1),x2,max(p.y1,y2),color,y+1);
}
int main(){
freopen("rect1.in","r",stdin);
freopen("rect1.out","w",stdout);
int a,b,i;
scanf("%d%d%d",&a,&b,&n);
for(i=1;i<=n;i++)
{
scanf("%d%d%d%d%d",&rec[i].x1,&rec[i].y1,&rec[i].x2,&rec[i].y2,&rec[i].cl);
}
rec[0].x1=0;
rec[0].y1=0;
rec[0].x2=a;
rec[0].y2=b;
rec[0].cl=1;
memset(ans,0,sizeof(ans));
for(i=n;i>=0;i--)
{
dos(rec[i].x1,rec[i].y1,rec[i].x2,rec[i].y2,rec[i].cl,i+1);
}
for(i=1;i<=3000;i++)
{
if(ans[i])
{
cout<<i<<" "<<ans[i]<<endl;
}
}
return 0;
}