Paint the Wall
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 877 Accepted Submission(s): 290
Problem Description
Here comes our future artist. See, he is painting again, this time on home's white wall, using different color of paint. Let me see, red, yellow, black, green... but why does he just paint rectangles? Pretty guy, seems he is fond of it.
So, after he's done his great job, the white wall has been filled with so many blocks of color. Of course, some color previously painted has been covered by some color painted later. Now, the little guy has some doubt that how many different colors have been left on the wall, and what are the areas of them. As a seven-year-old boy, he has just learned painting in kindergarten, math seems too difficult for him. So he turns to you, a college student good at math and programming, to help him figuring it out. Don't make him disappointed.
So, after he's done his great job, the white wall has been filled with so many blocks of color. Of course, some color previously painted has been covered by some color painted later. Now, the little guy has some doubt that how many different colors have been left on the wall, and what are the areas of them. As a seven-year-old boy, he has just learned painting in kindergarten, math seems too difficult for him. So he turns to you, a college student good at math and programming, to help him figuring it out. Don't make him disappointed.
Input
Input consists of multiple test cases, each describing "a great job" done by out little guy.
Each case begins with a line containing two integers, Height and Width, the size of the wall. The next line contains an integer N, which is the number of rectangles that have been painted. N lines follow, describing the rectangles in the order they were painted. Each line contains five integers, Top, Left, Bottom, Right, and Color, giving out the position, size and color information of the rectangle.
The range of Height and Width is [1, 10000]. There will be at least 1, and at most 100 rectangles to be painted. For each rectangle, Top and Bottom is in the range [0, Height], Left and Right is in the range [0, Width]. Bottom is strictly greater than Top, and Right is strictly greater than Left. Color will be in the range [1, 100].
The top-left coordinate of the wall is (0, 0), and the bottom-right coordinate of the wall is (Height, Width), as shown below.
The last case is followed by a line containing two zeroes.
There is a blank line between two test cases.
Each case begins with a line containing two integers, Height and Width, the size of the wall. The next line contains an integer N, which is the number of rectangles that have been painted. N lines follow, describing the rectangles in the order they were painted. Each line contains five integers, Top, Left, Bottom, Right, and Color, giving out the position, size and color information of the rectangle.
The range of Height and Width is [1, 10000]. There will be at least 1, and at most 100 rectangles to be painted. For each rectangle, Top and Bottom is in the range [0, Height], Left and Right is in the range [0, Width]. Bottom is strictly greater than Top, and Right is strictly greater than Left. Color will be in the range [1, 100].
The top-left coordinate of the wall is (0, 0), and the bottom-right coordinate of the wall is (Height, Width), as shown below.
(0,0) (0,W) --------------- | | | | | | | | | | --------------- (H,0) (H,W)
The last case is followed by a line containing two zeroes.
There is a blank line between two test cases.
Output
For each painting, first output "Case X:" in a single line where X is the case number starting form 1. Then output the colors left and their areas, one color per line, in the order of color numbers (increasing). For each color, you should output the color number, a blank space, and the area of this color on the wall. After that, you should output a single line "There is M color left on the wall." or "There are M colors left on the wall.", depending on M, which is the number of colors left on the wall.
Output a blank line between two test cases.
Output a blank line between two test cases.
Sample Input
10 5 1 1 1 2 2 2 4 4 2 0 0 3 3 1 2 2 4 4 2 0 0
Sample Output
Case 1: 2 1 There is 1 color left on the wall. Case 2: 1 8 2 4 There are 2 colors left on the wall.这题需要离散化,把矩形分割成几行,每行都有一个宽度,线段树记录这个宽度的区间是否被覆盖,矩形从输入的最后一个开始遍历,再遍历矩形的每一行的区间,算出未覆盖的宽度就可以算出面积,然后通过线段树覆盖当前区间。#include <iostream> #include <cstdio> #include <vector> #include <map> using namespace std; const int maxn1 = 50000; const int maxn2 = 110; struct tree{ int l , r; bool cover; }a[4*maxn1]; struct rectangle{ int Top , Bottom , Left , Right , c; rectangle(int top = 0, int bottom = 0, int left = 0, int right = 0, int C = 0){ Top = top , Bottom = bottom , Left = left , Right = right , c = C; } }; int color[maxn2] , H , W , xsize , ysize; vector<rectangle> R; map<int , int> X , Y; vector<int> x , y; void pushdown(int k){ if(a[k].l+1 < a[k].r && a[k].cover){ a[2*k].cover = true; a[2*k+1].cover = true; } } void build(int l , int r , int k){ a[k].l = l; a[k].r = r; a[k].cover = false; if(l+1 < r){ int mid = (l+r)/2; build(l , mid , 2*k); build(mid , r , 2*k+1); } } void add(int l , int r , int k){ if(l <= a[k].l && a[k].r <= r){ a[k].cover = true; }else{ int mid = (a[k].l+a[k].r)/2; if(mid >= r) add(l , r , 2*k); else if(mid <= l) add(l , r , 2*k+1); else{ add(l , mid , 2*k); add(mid , r , 2*k+1); } } } int querry(int l , int r , int k){ if(a[k].cover) return 0; if(a[k].l+1 >= a[k].r){ if(a[k].cover) return 0; //cout << a[k].r%xsize << "=" << x[a[k].r%xsize] <<endl; return x[a[k].r%xsize]-x[a[k].l%xsize]; } pushdown(k); int mid = (a[k].l+a[k].r)/2; if(mid >= r) return querry(l , r , 2*k); else if(mid <= l) return querry(l , r , 2*k+1); else return querry(l , mid , 2*k)+querry(mid , r , 2*k+1); } void initial(){ for(int i = 0; i < maxn2; i++) color[i] = 0; X.clear(); Y.clear(); x.clear(); y.clear(); R.clear(); } void readcase(){ int top , bottom , left , right , C , N; cin >> N; for(int i = 0 ; i <N;i++){ scanf("%d%d%d%d%d" , &top , &left , &bottom , &right , &C); R.push_back(rectangle(top , bottom , left , right , C)); X[left] = 0; X[right] = 0; Y[top] = 0; Y[bottom] = 0; } int cnt = 0; for(map<int , int>::iterator it = X.begin(); it != X.end(); it++){ it->second = cnt++; x.push_back(it->first); } cnt = 0; for(map<int , int>::iterator it = Y.begin(); it != Y.end(); it++){ it->second = cnt++; y.push_back(it->first); } } void computing(){ xsize = x.size(); ysize = y.size(); //cout << xsize << " " << ysize << "LL"<<endl; build(0 , xsize*ysize+1 , 1); for(int i = R.size()-1; i >= 0; i--){ for(int k = Y[R[i].Top]; k < Y[R[i].Bottom]; k++){ int w = querry(k*xsize+X[R[i].Left] , k*xsize+X[R[i].Right] , 1); //cout << k*xsize+X[R[i].Left] << " " << k*xsize+X[R[i].Right] << " " <<w <<endl; add(k*xsize+X[R[i].Left] , k*xsize+X[R[i].Right] , 1); color[R[i].c] += (y[k+1]-y[k])*w; } } int ans = 0; for(int i = 0; i < maxn2; i++){ if(color[i] != 0){ ans++; cout << i << " " << color[i] <<endl; } } if(ans == 1) printf("There is 1 color left on the wall.\n"); else printf("There are %d colors left on the wall.\n" , ans); } int main(){ int t = 1; while(cin >> H >>W && (H != 0|| W!= 0)){ initial(); readcase(); if(t > 1) printf("\n"); printf("Case %d:\n" , t++); computing(); } return 0; }