题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=18052
题意:给定一个方格,初始化其所有格子为1(白色)。按顺序给出一些矩形,给出方式是左下坐标和右上坐标还有它的值。后一个矩形对前一个有覆盖效果。最后按照从小到大值顺序输出这个值在方格中有多少个。
思路:递归,分割矩阵。
注意最后输出的时候i只能从1遍历到2500,因为数据好像存在color大于2500的情况,而这是不合法的。
源码:
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <iostream>
using namespace std;
int const MAXN = 2500+5;
struct DD
{
int x1,x2,y1,y2;
int colo;
void init(int a,int b,int c,int d,int e){x1=a,y1=b,x2=c,y2=d,colo=e;}
}dot[MAXN];
int n,ans[MAXN];
int cal(int x1,int y1,int x2,int y2,int k)
{
int tt;
while(k<n-1 && (x1>dot[k+1].x2 || x2<dot[k+1].x1 || y1>dot[k+1].y2 || y2<dot[k+1].y1))
k++;
if(k==n-1){
return (x2-x1)*(y2-y1);
}
// printf("now %d %d %d %d \nnext %d %d %d %d\n",x1,y1,x2,y2,dot[k+1].x1,dot[k+1].y1,dot[k+1].x2,dot[k+1].y2);
int res = 0;
if(x1<dot[k+1].x1){
res += tt = cal(x1,y1,dot[k+1].x1,y2,k+1);
x1 = dot[k+1].x1;
// printf("tt = %d\n",tt);
}
if(x2>dot[k+1].x2){
res += tt = cal(dot[k+1].x2,y1,x2,y2,k+1);
x2 = dot[k+1].x2;
// printf("tt = %d\n",tt);
}
if(y1<dot[k+1].y1){
res += tt = cal(x1,y1,x2,dot[k+1].y1,k+1);
y1 = dot[k+1].y1;
// printf("tt = %d\n",tt);
}
if(y2>dot[k+1].y2){
res += tt = cal(x1,dot[k+1].y2,x2,y2,k+1);
y2 = dot[k+1].y2;
// printf("tt = %d\n",tt);
}
return res;
}
int main()
{
// int t;
// scanf("%d",&t);
int A,B;
while(scanf("%d%d%d",&A,&B,&n)!=EOF){
for(int i=0; i<n; i++){
int a,b,c,d,e;
scanf("%d%d%d%d%d",&a,&b,&c,&d,&e);
dot[i].init(a,b,c,d,e);
}
int temp = 0;
memset(ans,0,sizeof(ans));
for(int i=n-1; i>=0; i--){
// printf("for i = %d\n",i);
int j = cal(dot[i].x1,dot[i].y1,dot[i].x2,dot[i].y2,i);
ans[dot[i].colo] += j;
temp += j;
}
ans[1] += A*B-temp;
for(int i=1; i<=2500; i++)
if(ans[i])
printf("%d %d\n",i,ans[i]);
}
return 0;
}
/*
20 20 2
1 1 10 10 2
2 2 9 9 3
*/