Given an array of A of N integers which represent stick lengths, we have to report the maximal area over all the rectangles that we can form with the given sticks without breaking any.
EXPLANATION:
The problem is a simple one based on a very basic property of all rectangles: the opposite sides of a rectangle are parallel, and hence, equal in length. The area of a rectangle is given by base B multiplied by height H. Now, to maximise the area, we simply need to maximise the length of sticks we choose as our B and H. This is pretty intuitive but we can also invoke the exchange argument method (page 3 of link) to give a more formal argument as proof of why this works (left to reader as a simple learning exercise).
Now we come to the implementation detail of the above mentioned algorithm. Note that N and A_{max} both range between 1 and 10^3. So, one way is that we simply keep an array Count of length 10^3 wherein Count[i] is the number of sticks of length i that we have. Once we have populated this structure, we can simply scan from 10^3 down to 1. If while scanning, we can find one field which has more than 3 sticks, then that i can be our height and base both; at this point we terminate our scan. If we find a field that has more than 1 stick, we can make it either our height or base and continue our scan to find a value for the other one. If at the end of scan we don’t find at least two i for which the count is more than 1, then we output -1 since no rectangle can be formed.
The other implementation can be by using a map instead of an array. In that case, if the N is much smaller than A_{max}, we can get a better performance. Both of the implementations easily pass for the given constraints.
Please see editorialist’s/setter’s program for implementation details.
COMPLEXITY:
\mathcal{O}(N\log N) or \mathcal{O}(A_{max}) per test case.
I implemented in c++ and java. In c++ I am getting run-time error when I am running the code in the code-compile-run here. And in Java it’s wrong answer.
First enter all the length of the sticks in an array, sort it in O(nlogn) and then traverse the array from the right end, checking for multiple instances of any stick. This also covers the special case of a square.
A different approach,which has O(N*logN) time complexity but uses Only One Array is as follows:
After storing the array containing the lengths of sticks, sort it.
We must note that the same lengths will automatically come together after sorting.
For example,
the array 5 2 8 3 1 2 4 3 5
becomes 1 2 2 3 3 4 5 5 8
Then if we traverse the array from backwards picking up the first two occurrences of a pair of same numbers(for e.g (5,5) would be the first occurrence and (3,3) would be the second in this case.Don’t forget to break the loop here. )
the answer would be 5*3=15.If we are unable to find two occurrences we print -1.
The JAVA solution of the problem using this method is: