input | output |
---|---|
20 20 3 2 2 18 18 2 0 8 19 19 3 8 0 10 19 4 |
1 91 2 84 3 187 4 38 |
题意: 对照案例, 有20*20个格子, 有三次涂颜色的操作, 接下来涂颜色,输入坐标和颜色 llx, lly, urx, ury, color。 后涂会覆盖之前涂的,最后输出的是个个颜色的面积,没涂颜色的算颜色1。
做法: 几何,从第一个开始, 处理第一个的时候不断找其上层的 有没有覆盖他, 有的话去掉覆盖的部分继续 处理剩下的部分。
#include<stdio.h> #include<string.h> #define max(a,b) a>b?a:b #define min(a,b) a<b?a:b struct rectangle { int x1,y1,x2,y2; int c; }; int cal(int x1,int y1,int x2,int y2) { return (x2-x1)*(y2-y1); } rectangle rect[1100]; int area_num[2600];//1-2500 int area_cal(int x1,int y1,int x2,int y2,const int& k,const int& n) { int kk; for(int i=k+1;i<=n+1;i++) { if(i==n+1) return cal(x1,y1,x2,y2); if(x1>=rect[i].x2 ||x2<=rect[i].x1 ||y1>=rect[i].y2 ||y2<=rect[i].y1)//没有覆盖 continue; else { kk=i; break; } } int sum=0; if(x1<rect[kk].x1) { sum+=area_cal(x1,y1,rect[kk].x1,y2,kk,n); x1=rect[kk].x1; } if(x2>rect[kk].x2) { sum+=area_cal(rect[kk].x2,y1,x2,y2,kk,n); x2=rect[kk].x2; } if(y1<rect[kk].y1) { sum+=area_cal(x1,y1,x2,rect[kk].y1,kk,n); y1=rect[kk].y1; } if(y2>rect[kk].y2) { sum+=area_cal(x1,rect[kk].y2,x2,y2,kk,n); y2=rect[kk].y2; } return sum; } int main() { int a,b,n; while(scanf("%d%d%d",&a,&b,&n)!=EOF) { memset(area_num,0,sizeof area_num); area_num[1]=a*b; for(int i=1;i<=n;i++) { scanf("%d%d%d%d%d",&rect[i].x1,&rect[i].y1,&rect[i].x2,&rect[i].y2,&rect[i].c); } for(int i=n;i>=1;i--) { int tem=area_cal(rect[i].x1,rect[i].y1,rect[i].x2,rect[i].y2,i,n); area_num[rect[i].c]+=tem; area_num[1]-=tem; } for(int i=1;i<=2500;i++) { if(area_num[i]) printf("%d %d\n",i,area_num[i]); } } return 0; } /* 20 20 3 2 2 18 18 2 0 8 19 19 3 8 0 10 19 4 4 4 2 1 1 3 3 3 2 2 4 4 2 右上 4 4 2 1 1 3 3 3 0 2 2 4 2 左上 1 91 2 84 3 187 4 38 */