【分段哈希】H. Paint the Wall
https://www.bnuoj.com/v3/contest_show.php?cid=9147#problem/H
【题意】
在一个长为H,宽为W的白墙上选一个矩形区域涂颜色,后涂的颜色会覆盖先涂的,题目给出n(n<=100)个矩形区域和对应的颜色。
求最后墙上每种颜色的面积是多少,共有多少种颜色。
【思路】
将墙分成一块一块的矩形区域,对每个区域判断最后涂的颜色是什么,将其面积加到对应的颜色上。关键是怎样将矩形分块:
将竖线(所有矩形的left和right)离散化,从左到右枚举相邻的竖线;
对固定的两条竖线,枚举覆盖这两条竖线的矩形,再离散化横线(所有合法矩形的top和bottom);
对当前的每个矩形区域,遍历所有的合法矩形,判断哪个是最后涂的。
时间复杂度是O(2n*2n*n)即O(n^3)。
【Accepted】
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<string> 5 #include<cmath> 6 #include<algorithm> 7 8 using namespace std; 9 int H,W; 10 int n; 11 const int maxn=4e2+5; 12 int cnt; 13 struct Rec 14 { 15 int T,L,B,R,c,o; 16 void input(int o_) 17 { 18 o=o_; 19 scanf("%d%d%d%d%d",&T,&L,&B,&R,&c); 20 } 21 }rec[maxn/2]; 22 int area[maxn]; 23 vector<int> v; 24 int w[maxn]; 25 int h[maxn]; 26 void init() 27 { 28 cnt=0; 29 memset(area,0,sizeof(area)); 30 } 31 int main() 32 { 33 int cas=0; 34 while(~scanf("%d%d",&H,&W)) 35 { 36 if(!H&&!W) 37 { 38 break; 39 } 40 init(); 41 scanf("%d",&n); 42 for(int i=1;i<=n;i++) 43 { 44 rec[i].input(i); 45 w[++cnt]=rec[i].L; 46 w[++cnt]=rec[i].R; 47 } 48 getchar(); 49 sort(w+1,w+cnt+1); 50 cnt=unique(w+1,w+cnt+1)-(w+1); 51 for(int i=1;i<cnt;i++) 52 { 53 v.clear(); 54 int tot=0; 55 for(int k=1;k<=n;k++) 56 { 57 if(rec[k].L<=w[i]&&w[i+1]<=rec[k].R) 58 { 59 h[++tot]=rec[k].T; 60 h[++tot]=rec[k].B; 61 v.push_back(k); 62 } 63 } 64 sort(h+1,h+tot+1); 65 tot=unique(h+1,h+tot+1)-(h+1); 66 int sz=v.size(); 67 for(int k=1;k<tot;k++) 68 { 69 int pos=-1; 70 for(int j=0;j<sz;j++) 71 { 72 if(rec[v[j]].T<=h[k]&&h[k+1]<=rec[v[j]].B) 73 { 74 if(pos<rec[v[j]].o) 75 { 76 pos=rec[v[j]].o; 77 } 78 } 79 } 80 if(pos!=-1) 81 { 82 area[rec[pos].c]+=(w[i+1]-w[i])*(h[k+1]-h[k]); 83 } 84 } 85 } 86 if(cas) 87 { 88 puts(""); 89 } 90 printf("Case %d:\n",++cas); 91 int ans=0; 92 for(int i=1;i<=100;i++) 93 { 94 if(area[i]>0) 95 { 96 ans++; 97 printf("%d %d\n",i,area[i]); 98 } 99 } 100 if(ans==1) 101 { 102 puts("There is 1 color left on the wall."); 103 } 104 else 105 { 106 printf("There are %d colors left on the wall.\n",ans); 107 } 108 } 109 return 0; 110 }