Wooden Toy Festival (Codeforces 1840D)
Tags: Greedy, binary search

In a small town, there is a workshop specializing in woodwork. Since the town is small, only three carvers work there.Soon, a wooden toy festival is planned in the town. The workshop employees want to prepare for it.They know that $$$n$$$ people will come to the workshop with a request to make a wooden toy. People are different and may want different toys. For simplicity, let's denote the pattern of the toy that the $$$i$$$-th person wants as $$$a_i$$$ ($$$1 \le a_i \le 10^9$$$).Each of the carvers can choose an integer pattern $$$x$$$ ($$$1 \le x \le 10^9$$$) in advance, different carvers can choose different patterns. $$$x$$$ is the integer. During the preparation for the festival, the carvers will perfectly work out the technique of making the toy of the chosen pattern, which will allow them to cut it out of wood instantly. To make a toy of pattern $$$y$$$ for a carver who has chosen pattern $$$x$$$, it will take $$$|x - y|$$$ time, because the more the toy resembles the one he can make instantly, the faster the carver will cope with the work.On the day of the festival, when the next person comes to the workshop with a request to make a wooden toy, the carvers can choose who will take on the job. At the same time, the carvers are very skilled people and can work on orders for different people simultaneously.Since people don't like to wait, the carvers want to choose patterns for preparation in such a way that the maximum waiting time over all people is as small as possible.Output the best maximum waiting time that the carvers can achieve.

Input: The first line of the input contains an integer $$$t$$$ ($$$1 \le t \le 10^4$$$) — the number of test cases.Then follow the descriptions of the test cases.The first line of a test case contains a single integer $$$n$$$ ($$$1 \le n \le 2 \cdot 10^5$$$) — the number of people who will come to the workshop.The second line of a test case contains $$$n$$$ integers $$$a_1, a_2, a_3, \dots, a_n$$$ ($$$1 \le a_i \le 10^9$$$) — the patterns of toys.The sum of all $$$n$$$ values over all test cases does not exceed $$$2 \cdot 10^5$$$.

Output: Output $$$t$$$ numbers, each of which is the answer to the corresponding test case — the best maximum waiting time that the carvers can achieve.

Note: In the first example, the carvers can choose patterns $$$1$$$, $$$7$$$, $$$9$$$ for preparation.In the second example, the carvers can choose patterns $$$3$$$, $$$30$$$, $$$60$$$ for preparation.In the third example, the carvers can choose patterns $$$14$$$, $$$50$$$, $$$85$$$ for preparation.

Sample Inputs:
5
6
1 7 7 9 9 9
6
5 4 2 1 30 60
9
14 19 37 59 1 4 4 98 73
1
2
6
3 10 1 17 15 11

Sample Outputs:
0
2
13
0
1

Solution (Python):
import math
for op in range(int(input(''))):
    n = int(input())
    a = list(map(int, input().split(' ')))
    s_a = set(a)
    sorted_a = list(a)
    sorted_a.sort()
    if len(s_a) <= 3:
        print(0)
        continue
    t = True
    a1 = [sorted_a[0]]
    a2 = [sorted_a[-1]]
    ind1 = 1
    ind2 = -2
    hook1 = a1[0]
    hook2 = a2[0]
    while t:
        v1 = sorted_a[ind1]
        v2 = sorted_a[ind2]
        if v1 - hook1 < v2 - v1 and v1 - hook1 <= hook2 - v2:
            a1.append(v1)
            ind1 += 1
        elif hook2 - v2 < v2 - v1 and hook2 - v2 <= v1 - hook1:
            a2.append(v2)
            ind2 -= 1
        elif v2 - v1 <= hook2 - v2 and v2 - v1 <= v1 - hook1:
            t = False
            break
        else:
            break
    c = sorted_a[ind1:ind2 + 1]
    print(math.ceil(max(a1[-1] - a1[0], a2[0] - a2[-1], c[-1] - c[0]) / 2))

Solution (Python):
import sys
from math import ceil
from bisect import bisect, bisect_left, bisect_right
input = lambda : sys.stdin.readline().rstrip()

def solution(n, a):
    a = sorted(list(set(a)))
    if len(a) < 4:
        return 0
    (mn, mx) = (min(a), max(a))
    (l, r) = (1, ceil((mx - mn) / 6))
    while l + 1 < r:
        mid = (l + r + 1) // 2
        (ll, rr) = (mn + 2 * mid, mx - 2 * mid)
        (idx_l, idx_r) = (bisect(a, ll), bisect_left(a, rr) - 1)
        if abs(a[idx_r] - a[idx_l]) > 2 * mid and idx_l < idx_r:
            l = mid
        else:
            r = mid
    (ll, rr) = (mn + 2 * l, mx - 2 * l)
    (idx_l, idx_r) = (bisect(a, ll), bisect_left(a, rr) - 1)
    if abs(a[idx_r] - a[idx_l]) <= 2 * l or idx_l >= idx_r:
        return l
    else:
        return r
for _ in range(int(input())):
    n = int(input())
    a = [int(i) for i in input().split()]
    print(solution(n, a))

Solution (Python):
for _ in range(int(input())):
    n = int(input())
    nums = list(map(int, input().split()))
    if n <= 3:
        print(0)
        continue
    nums.sort()
    ans = float('inf')
    (l1, r1) = (0, n - 3)
    while l1 <= r1:
        i = (l1 + r1) // 2
        m = (nums[i] - nums[0] + 1) // 2
        (l, r) = (i + 1, n - 2)
        m1 = float('inf')
        while l <= r:
            mid = (l + r) // 2
            if mid >= n - 1:
                break
            x = (nums[mid] - nums[i + 1] + 1) // 2
            y = (nums[n - 1] - nums[mid + 1] + 1) // 2
            m1 = min(m1, max(x, y))
            if x > y:
                r = mid - 1
            elif y > x:
                l = mid + 1
            else:
                break
        if m > m1:
            r1 = i - 1
        elif m1 >= m:
            l1 = i + 1
        m = max(m, m1)
        ans = min(ans, m)
    print(ans)