Suppose we are given an array mat where the elements are of this form [p, q, r] where p, q are geometric coordinates and r is a radius value. The items in the array are the locations of bombs in a rectangular area of a given width w. The rectangle is infinitely long and is bounded by x coordinates x = 0 to x = w. The r value in the bombs position signifies the safety radius of a bomb, meaning anything less than that radius of the bomb will engage it. So, what we have to do is to draw a continuous path that starts below every bomb and ends above every bomb without engaging any one of them. We will print True if we can draw this line, otherwise, we print False.
So, if the input is like mat =
0 | 1 | 2 |
3 | 2 | 1 |
2 | 1 | 1 |
, w = 4; then the output will be False.
To solve this, we will follow these steps −
- Define a function insec() . This will take p, q
- x1 := p[1], x2 := p[2]
- y2 := q[1], y4 := q[2]
- r1 := p[3], r2 := q[3]
- d := (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)
- dec :=(r1 + r2) *(r1 + r2)
- return True if d <= dec, else return False
- sort the matrix based on the x coordinate values
- temp := a new list
- if mat[0][0] - mat[0][2] > 0, then
- return True
- for each p, q, r in mat, do
- min_wid := p - r
- max_wid := p + r
- if size of temp is same as 0, then
- add list containing (p + r, p, q, r, p - r, p + r) at the end of temp
- otherwise,
- mx := maximum of (the position in temp where the list [p - r, -p, q, r, 0, 0] can be inserted maintaining the sorted order - 1) , 0
- in_list := a new list containing elements (p + r, p, q, r, p - r, p + r)
- for i in range mx to size of temp, do
- if insec(temp[i], in_list) is True, then
- max_wid = maximum of (max_wid, temp[i, -1])
- min_wid = minimum of (min_wid, temp[i, -2])
- if insec(temp[i], in_list) is True, then
- second last element of in_list := min_wid
- last_element of in_list := max_wid
- insert in_list in temp maintaining the sorted order
- if min_wid <= 0 and max_wid >= w, then
- return False
- return True
Example
Let us see the following implementation to get better understanding −
from bisect import bisect_left, insort def solve(mat, w): mat.sort(key=lambda i: i[0] - i[2]) temp = [] if mat[0][0] - mat[0][2] > 0: return True for p, q, r in mat: min_wid, max_wid = p - r, p + r if len(temp) == 0: temp.append([p + r, p, q, r, p - r, p + r]) else: mx = max(bisect_left(temp, [p - r, -p, q, r, 0, 0]) - 1, 0) in_list = [p + r, p, q, r, p - r, p + r] for i in range(mx, len(temp)): if insec(temp[i], in_list): max_wid = max(max_wid, temp[i][-1]) min_wid = min(min_wid, temp[i][-2]) in_list[-2] = min_wid in_list[-1] = max_wid insort(temp, in_list) if min_wid <= 0 and max_wid >= w: return False return True def insec(p, q): x1, y1, x2, y2 = p[1], p[2], q[1], q[2] r1, r2 = p[3], q[3] d = (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2) dec = (r1 + r2) * (r1 + r2) return d <= dec print(solve([[0, 1, 2],[3, 2, 1], [2, 1, 1]], 4))
Input
[[0, 1, 2],[3, 2, 1], [2, 1, 1]], 4
Output
False