大体看懂题意后,第一反应就是和以前见过的离散化+线段树的一个题目的二维情况。不过感觉数据规模不大,暴力就行,对离散化有点信心不足啊,确实不怎么会离散。。。好在这个题目a,b都是在10000以内,搞一个数组哈希了一下。主体部分就是离散之后,暴力模拟整个过程,时间复杂度目测应该是2000*2000*1000,想水一下。。。代码搞了好久,然后提交发现内存爆了。。。时间倒是可以过,试着提交了几次1500*1500的数组可以过,但是按我离散的方式一定要开2000*2000的数组,悲剧啊,最后一组数组一直过不了,本地程序运行结果是对的。。。唉,查了一下题解,发现只要变一下顺序,不仅可以提高查找效率,也不用浪费内存去记录状态了。这个题目很好。。。
思路:枚举离散后的每一个小矩形,然后从后往前查找是否被颜色覆盖,如果没有找到颜色就是1。
1 /* 2 ID: cuizhe 3 LANG: C++ 4 TASK: rect1 5 */ 6 #include <iostream> 7 #include <cstdio> 8 #include <cstring> 9 #include <cmath> 10 #include <algorithm> 11 using namespace std; 12 int x3[2501],y3[1001],x2[1001],y2[1001],co[1001]; 13 int x[2003],y[2003]; 14 int r[10001],c[10001]; 15 int coc[2501]; 16 int main() 17 { 18 int a,b,n,i,j,k,num,rr,cc; 19 freopen("rect1.in","r",stdin); 20 freopen("rect1.out","w",stdout); 21 scanf("%d%d%d",&a,&b,&n); 22 for(i = 1;i <= n;i ++) 23 { 24 scanf("%d%d%d%d%d",&x3[i],&y3[i],&x2[i],&y2[i],&co[i]); 25 x[i*2-1] = x3[i]; 26 x[i*2] = x2[i]; 27 y[i*2-1] = y3[i]; 28 y[i*2] = y2[i]; 29 } 30 sort(x+1,x+2*n+1); 31 sort(y+1,y+2*n+1); 32 r[0] = 1; 33 for(i = 1,num = 2;i <= 2*n;i ++) 34 { 35 if(!r[x[i]]) 36 r[x[i]] = num++; 37 } 38 if(!r[a]) 39 r[a] = num++; 40 rr = num-1; 41 c[0] = 1; 42 for(i = 1,num = 2;i <= 2*n;i ++) 43 { 44 if(!c[y[i]]) 45 c[y[i]] = num++; 46 } 47 if(!c[b]) 48 c[b] = num++; 49 cc = num-1; 50 num = 1; 51 for(i = 0;i <= 10000;i ++) 52 { 53 if(r[i]) 54 x[num++] = i; 55 } 56 num = 1; 57 for(i = 0;i <= 10000;i ++) 58 { 59 if(c[i]) 60 y[num++] = i; 61 } 62 for(i = 1;i <= rr-1;i ++) 63 { 64 for(j = 1;j <= cc-1;j ++) 65 { 66 for(k = n;k >= 1;k --) 67 { 68 if(x3[k]<=x[i]&&y3[k]<=y[j]&&x2[k]>=x[i+1]&&y2[k]>=y[j+1]) 69 { 70 coc[co[k]] += (x[i+1]-x[i])*(y[j+1]-y[j]); 71 break; 72 } 73 } 74 if(k == 0) 75 { 76 coc[1] += (x[i+1]-x[i])*(y[j+1]-y[j]); 77 } 78 } 79 } 80 for(i = 1;i <= 2500;i ++) 81 { 82 if(coc[i] != 0) 83 printf("%d %d\n",i,coc[i]); 84 } 85 return 0; 86 }