KTHCON - Editorial

PROBLEM LINK:

Contest
Practice

Authors: Jaub Safin
Testers: Vasya Antoniuk
Translators: Vasya Antoniuk (Russian), Team VNOI (Vietnamese) and Hu Zecong (Mandarin)
Editorialist: Praveen Dhinwa

DIFFICULTY:

Medium

PREREQUISITES:

geometry, convex hull, rotating callipers technique

PROBLEM:

You are given N points in 2-D plane. All of the points are distinct. No three of them are collinear.

A polygon is called a 1-concave if it is a simple polygon (its sides don’t intersect or touch) which has at least 1 concave interior angle.

Let S denote the maximum area of a 1-concave polygon with its vertices being choosen from the given N points. You have to output 2 * S.

If it is not possible to construct a 1-concave polygon, output -1.

QUICK EXPLANATION:

If all N points lie on the convex hull, then output -1.

Otherwise construct convex hull of all the points. Also compute an inner convex hull of all points lying inside the just constructed convex hull (outer convex hull).

We can reduce the problem to find the minimum area triangle with two of its vertices belonging to the side of outer convex polygon and the other vertex lying inside the outer convex polygon (to be precise, on the inner convex hull).

We iterate over side of outer convex hull one by one in clockwise direction and consider the side to be the base of the triangle and want to minimize height by taking the third point on the inner hull. Note that third point which has minimum value of height for a fixed side rotates clockwise when we move the side in clockwise direction.

The above observation allows us to apply a two pointer method (or famously called rotating callipers method) to solve the problem in \mathcal{O} (N \, log N) time.

EXPLANATION:

If the constraint of desired polygon being 1-concave polygon is not there, then the maximum area polygon will be the convex hull of all the points.

If all N points lie on the convex hull, then it is not possible to construct a 1-concave polygon.

Now, let us think how we can use convex hull of the points to construct a 1-concave polygon.

Let us think in the reverse way. What minimum amount of area can we lose from the convex hull for getting at least one concave angle.

We can note that if the desired polygon has more than one concave angle, we are going to lose more area. So, we will have just one concave angle, i.e. we will need to create a triangle with two of its vertices lying on the convex hull and other among the points lying inside the convex hull.

Now we can note that if the two vertices on the convex hull are not the adjacent one (i.e. they don’t form a side of convex hull), then we are going to lose more area.

So, now our problem reduces to find the minimum area triangle with two of its vertices belonging to the side of convex polygon and the other vertex lying inside the convex polygon.

A direct implementation of this idea can be done in \mathcal{O}(N^2) time by iterating over each side of the polygon and by trying all the inside points to be a candidate third point of the triangle.

This won’t pass for N = 10^5, we need to make more observations to improve our algorithm.

Let us construct convex hull of the inner points (the points inside the convex hull of all points). From now on, we will distinguish between the two convex hulls by calling them outer and inner convex hulls. We can note that third point of the triangle, which will give minimum area for a side will always lie on inner convex hull.
This can be proved intuitively as follows. Think the side of the outer convex hull as a base of the triangle and we want to minimize the height by picking the third point. Imagine sweeping a line parallel to the side towards the inner convex hull, you can notice that it can never hit a point lying strictly inside the inner convex hull without hitting some point on the inner convex hull first.

Now, we make the final and most crucial observation. When we move along the sides of outer convex hull in clockwise direction, the third point of the triangle also moves clockwise. This observation can be used to have a solution using two pointer method in which first pointer denotes iterates over sides of outer convex hull and the second pointer over the third point on inner convex hull. As we know when we increase first pointer, the second pointer can only increase. Also second pointer can move along the inner convex at most once. So, it will take at max \mathcal{O}(N) iterations.

In the above picture,

| Side   | Third point |    
|--------|-------------|    
| (1, 2) |      2      |   
| (2, 3) |      2      |   
| (3, 4) |      3      |   
| (4, 5) |      4      |   
| (5, 6) |      5      |   
| (6, 1) |      1      |   

So, we can notice that when we move along the side in clockwise order, the third point also moves along clockwise order.

long long minTriangleArea = (long long) 1e18;
int second_pointer = 0;
for(int first_pointer = 0; first_pointer < outerHull.size(); first_pointer++) {
    long long curArea = abs(triangle_area(outer[first_pointer], 
    	outerHull[(first_pointer+1) % outerHull.size()], outerHull[second_pointer]));

    while (true) {
        long long newArea = abs(triangle_area(outerHull[first_pointer], 
        	outerHull[(first_pointer+1) % outerHull.size()], 
        	innerHull[(second_pointer+1) % innerHull.size()]));

        if (newArea < curr) {
            curArea = newArea;
            second_pointer = (second_pointer+1) % innerHull.size();
        }
        else {
            break;
        }
    }

    minTriangleArea = min(minTriangleArea, curArea);
}

You can note that we will never have to deal with floating point calculations as the final desired answer is 2 * S.

Time Complexity:

We need to build outer and inner convex hull. Building a convex of N points can be done in \mathcal{O}(N \, log N) time. The two pointer method stated above takes \mathcal{O}(N) time.

So time complexity of the program will be \mathcal{O}(N \, log N) time, which will easily fit in time for N = 10^5.

AUTHOR’S AND TESTER’S SOLUTIONS:

setter
tester

1 Like

Tag it with COOK68 instead of COOK58

Thanks, done.

We can find the minimum area triangle by finding the closest point to each side of convex hull using the “Convex hull trick” ( the trick used in dynamic programming ) Link to Solution

@gvaibhav21 could you provide logic behind your solution as well?

What should be the answer for

1
5
-2 -2
2 2
-2 2
2 -2
0 2

Both tester’s and setter’s solution return 32, but in my opinion it should be -1, because the convex hull is clearly the first 4 points, and the fifth one is on the boundary, so virtually also in the convex hull. This means that we cannot construct a 1-concave polygon because there are no inside points.

EDIT: Ok found my mistake: I overlooked the condition “no three points colinear”, which makes the above testcase invalid.

Problem statement clearly says that there can not be three or more collinear points. This condition is violated in your example.

Correction in line ->
outerHull[(first_pointer+1) % outerHull.size()], outerHull[second_pointer]));

it should be->
outerHull[(first_pointer+1) % outerHull.size()], innerHull[second_pointer]));

1 Like

I tried a rather brute force soln on second part of ques ( i.e I found the convex hull and then found the points which are not in convex hull and after that i found the area of minimum triangle and subtracted that from area of convex hull , but i am getting wrong ans , can anyone help me . Here is my solution https://www.codechef.com/viewsolution/9715190

@gvaibhav21 My algorithm looks similar to yours but I was getting RTE on mine. Any hints for the test case which will give RTE on my code? Here is my code: Solution

what if inner convex hull consists of more sides than that of outer convex hull?

In tester’s solution what algorithm is used for finding Convex Hull?

Can I ask for more logical explanation about rotating callipers technique and its application?