Saint Louis University |
Computer Science 180
|
Dept. of Math & Computer Science |
Topic: | Bulletin Board |
Source Code: | bulletin.cpp |
Live Archive Ref#: | 4171 |
Pre-lab Due: |
Tuesday, 29 April 2014, 10:00am |
Submission Deadline: | Wednesday, 30 April 2014, 11:59pm |
Techniques: |
Sweepline Algorithm |
The pre-lab requirement must be completed and submitted individually.
The remainder of the lab activity should be completed working in pairs. One person should submit the result, making sure that both partners' names are clearly identified in that submission.
Please make sure you adhere to the policies on academic integrity in this regard.
Read the complete problem description and then determine what the expected output should be if given the following input:
Prelab input: | Prelab output: |
4 20 10 7 6 11 8 17 1 19 2 5 5 15 10 9 7 13 9 5 100 100 0 5 90 15 85 0 95 90 10 85 100 95 5 10 15 100 7 12 92 98 0 |
The ACM Student Chapter has just been given custody of a number of school bulletin boards. Several members agreed to clear off the old posters. They found posters plastered many levels deep. They made a bet about how much area was left clear, what was the greatest depth of posters on top of each other, and how much of the area was covered to this greatest depth. To determine each bet's winner, they made very accurate measurements of all the poster positions as they removed them. Because of the large number of posters, they now need a program to do the calculations. That is your job.
A simple illustration is shown above: a bulletin board 45 units wide by 40 high, with three posters, one with corners at coordinates (10, 10) and (35, 20), another with corners at (20, 25) and (40, 35), and the last with corners at (25, 5) and (30, 30). The total area not covered by any poster is 1300. The maximum number of posters on top of each other is 2. The total area covered by exactly 2 posters is 75.
Input: The input will consist of one to twenty data sets, followed by a line containing only 0. On each line the data will consist of blank separated nonnegative integers.
The first line of a dataset contains integers n w h, where n is the number of posters on the bulletin board, w and h are the width and height of the bulletin board. Constraints are 0 < n ≤ 100; 0 < w ≤ 50000; 0 < h ≤ 50000.
The dataset ends with n lines, each describing the location of one poster. Each poster is rectangular and has horizontal and vertical sides. The x and y coordinates are measured from one corner of the bulletin board. Each line contains four numbers xl yl xh and yh, where xl and yl, are the lowest values of the x and y coordinates in one corner of the poster and xh and yh are the highest values in the diagonally opposite corner. Each poster fits on the bulletin board, so 0 ≤ xl < xh ≤ w, and 0 ≤ yl < yh ≤ h.
Output: There is one line of output for each data set containing three integers, the total area of the bulletin board that is not covered by any poster, the maximum depth of posters on top of each other, and the total area covered this maximum number of times.
Caution: An approach examining every pair of integer coordinates might need to deal with 2 billion coordinate pairs.Example input: | Example output: |
3 45 40 10 10 35 20 20 25 40 35 25 5 30 30 1 20 30 5 5 15 25 2 2000 1000 0 0 1000 1000 1000 0 2000 1000 3 10 10 0 0 10 10 0 0 10 10 0 0 10 10 0 |
1300 2 75 400 1 200 0 1 2000000 0 3 100 |
The first key observation is that with a 50000 x 50000 grid, we cannot possible afford to allocate a two-dimensional array to represent the entire board, nor the time it would take to analyze each of the 2.5 billion positions. Instead, we ask you to use an approach known as a "sweepline" algorithm, and will will get you going by providing you with this partially complete program.
We scan the bulletin board from bottom to top, always keeping track of the current number of posters under a particular [x,x+1) region of the sweepline. As long as those numbers remain the same as we sweep, it is easy to calculate how much uncovered (i.e. zero-depth) area is being swept past, as well as how much of the area has the maximum depth thus far. The only change to those depths will occur when we sweep past the top of a current poster or the bottom of a new poster.
However, with a 50000 x 50000 grid, we cannot afford to move the sweepline one unit at a time along the y-axis. Instead, we want to find the significant events, namely times when we cross over the top or bottom of a poster. We define an Edge class to represent each horizontal edge of a poster, and we sort those edges by increasing y-coordinates (breaking ties intentionally so that the top edge of one poster is considered before the bottom edge of another poster with the same y-coodinate.
While sweeping, we maintain the following state information:
A "sweepline" declared as
vector<int> sweep(w,0);
The integer at sweep[x] represents the current number of posters
covering the unit [x,x+1). It is initialized so as to
have width w, and with all entries initially
set to zero.
For example, in the above picture, when the sweepline reaches y=15, this sweep vector should have contents:
[0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0]
A variable uncovered equal to the total area of uncovered board that has been swept past thus far.
A variable maxDepth equal to the maximum number of posters in one spot that has thus far been observed.
A variable maxCovered equal to the total area of the board having depth equal to maxDepth that has thus far been swept (for the current value of maxDepth).
A variable sweepZeros equal to the current number of entries of the sweepline that are equal to zero. In the above example, there are 20 zeros.
A variable sweepMax equal to the current number of entries of the sweepline that are equal to the current value of maxDepth. For example, maxDepth will be 2 by the time we reach y=15 in the above example, and sweepMax should be 5 for that sweepline, since there are five horizontal cells with such depth.
Your task is then to orchestrate the sweeping of the entire area, by looping through the sorted sequence of poster edges. For each one:
First, make sure to account for the motion of the sweepline from the previous event to this one. You may have been sweeping over some uncovered area as well as some maximally covered areas. Use the variables sweepZero and sweepMax, together with your knowledge of the previous and current y-coordinates.
If you are entering a new poster, increase the sweepline depth for each entry in the range [xl,xh).
While doing so, make sure to account for any changes in the
number of zeros under the sweepline, or the number of
entries equal to the maximum depth.
If you find yourself surpassing the previous maximum depth,
record the new depth and then set the
Again, make sure to account for any changes in the number of zeros under the sweepline, or the number of entries equal to the maximum depth.
You can run the automated judge's tests on turing to test the correctness of your program (although you must still formally submit the source code via the course website). If you are working on your own machine (or if you just want to examine the judge's inputs and expected outputs), we provide them here.