Editorial for MALD Contest 1 P6 - Scratch Cat and Painting
Submitting an official solution before solving the problem yourself is a bannable offence.
Author:
Hint 1
How can the area of the annuli/circles be approximated without cutting up both the x and y dimensions?
Hint 2
How can a Riemann sum be modified to work for circles? How can you easily extend it to work for Annuli?
Subproblem 1
Length of Union of Line SegmentsTo solve this problem, you must first be able to solve this subproblem. This can be done using Klee's Algorithm or coming up with your algorithm, as long as its complexity is .
An alternative to Klee's algorithm is to first sort the line segments by their starting point, then for every line:
- If its start point is greater than the current segment union endpoint: Add the difference of the current union end and start to our answer. Then start a new segment union by updating the union start and end variables.
- If its start point is less than or equal to the segment union endpoint, the line is connected to the current segment union. Check to see if the line's endpoint is greater than the segment union's endpoint. If so, the current segment union is extended by the line, meaning we should update the current segment union endpoint. Otherwise, the line is completely covered by the current segment union.
This algorithm is about twice as fast as Klee's algorithm because an array of size instead of is sorted. If you are tight on time, this algorithm can halve your runtime.
Subproblem 2
Riemann Sums: Approximating Area Under a FunctionA Riemann sum is an approximation for the area between a function and the x-axis. We can modify this idea to find the area bounded by circles (or annuli) instead of a function and the x-axis. Rather than finding the area between a function and the x-axis, you can use the upper and lower y-values of the circle as a bound for rectangles.
Rectangle-Based Riemann Sums
Left Sum | Middle Sum | Right Sum |
---|---|---|
Trapezoidal Sums
There are many Riemann sums types such as trapezoidal that achieve the same accuracy as rectangular using much fewer partitions. These are complex to modify for overlapping circles/annuli. For simplicity, use rectangle-based Riemann sums.
Full Solution
This problem is finding the area of the union of circles in subtask and annuli in subtask . Some complex solutions use multivariable calculus concepts, but and , allowing us to approximate the union of circles with rectangles. We can extend this idea to work for annuli (see Fig. 1).
The general idea is to break up circles into rectangles of width . Iterate each value with increments of . For each , calculate the sum of the union of rectangle heights at and multiply it by (rectangle width). The sum the segment union areas from each partition is the total area.
Figure 1. Modified Left Riemann Sum on Three Annuli
Figure 2. Modified Riemann Sums on Two Disjoint Unions
Figure 3. Expanded Circle Union
As seen in Fig 3., you can approximate the area by partitioning the circle from its minimum value to its maximum value. Overlapping regions should not be overcounted, so we calculate segment union length rather than the sum of lengths.
Each rectangle height is distance between the upper and lower value of the circle. These can be found by modifying the implicit equation for a circle:
For a circle, the lower bound for a rectangle is and the upper bound is . Find the segment for each circle at (if it's defined) and store them in a list. Find the length of the segment unions in the list and multiply it by (width). An annuli can have one or two segments, either , or and .
If there are multiple disjoint unions at , you can still multiply their total sum by . This works because .
Difference Between Left and Middle Sums
If there were no intersections, there wouldn't be a large difference because circles/annuli are symmetrical; over guesses cover gaps.For this problem, middle sums perform better due to the smaller over guesses and gaps, but it doesn't matter which one you use unless you are tight on time. In the reference solution, using middle sums allowed a value twice as large, cutting down runtime roughly in half. For every value, you should find the union sum at rather than at . This represents the middle of the rectangle rather than the left side.
In the reference solution, left sums was accepted a with maximum of , while middle sums with a maximum of .
Finding a Value
One option is trial and error, but you don't need to keep submitting until your solution gets TLE or AC.A better method is to approximate the minimum value by approximating the operations of your program.
For the intended solution, can approximate the operations performed. This approximation has instead of because there can be segments per annulus at many values and calculating segment union length also uses operations. Solving the equation gives about . You can definitely run operations within the time limit.
This may not be completely accurate, but it's a good place to start. The reference solution with runs in seconds with operations. The approximation was very accurate this time, partially a coincidence and because of the simple operations in the reference solution. This value can be made roughly times smaller (especially for C++ users), considering it ran in seconds on its worst case. The largest value accepted on the reference solution was (left) or (middle). Depending on your implementation, you may experience different results.
Intended Complexity:
Comments