Pursuit (Codeforces 1530C)
Tags: Greedy, binary search

You and your friend Ilya are participating in an individual programming contest consisting of multiple stages. A contestant can get between $$$0$$$ and $$$100$$$ points, inclusive, for each stage, independently of other contestants.Points received by contestants in different stages are used for forming overall contest results. Suppose that $$$k$$$ stages of the contest are completed. For each contestant, $$$k - \lfloor \frac{k}{4} \rfloor$$$ stages with the highest scores are selected, and these scores are added up. This sum is the overall result of the contestant. (Here $$$\lfloor t \rfloor$$$ denotes rounding $$$t$$$ down.)For example, suppose $$$9$$$ stages are completed, and your scores are $$$50, 30, 50, 50, 100, 10, 30, 100, 50$$$. First, $$$7$$$ stages with the highest scores are chosen — for example, all stages except for the $$$2$$$-nd and the $$$6$$$-th can be chosen. Then your overall result is equal to $$$50 + 50 + 50 + 100 + 30 + 100 + 50 = 430$$$.As of now, $$$n$$$ stages are completed, and you know the points you and Ilya got for these stages. However, it is unknown how many more stages will be held. You wonder what the smallest number of additional stages is, after which your result might become greater than or equal to Ilya's result, at least in theory. Find this number!

Input: Each test contains multiple test cases. The first line contains the number of test cases $$$t$$$ ($$$1 \le t \le 1000$$$). Description of the test cases follows.The first line of each test case contains a single integer $$$n$$$ ($$$1 \le n \le 10^5$$$) — the number of completed stages.The second line contains $$$n$$$ integers $$$a_1, a_2, \ldots, a_n$$$ ($$$0 \le a_i \le 100$$$) — your points for the completed stages.The third line contains $$$n$$$ integers $$$b_1, b_2, \ldots, b_n$$$ ($$$0 \le b_i \le 100$$$) — Ilya's points for the completed stages.It is guaranteed that the sum of $$$n$$$ over all test cases does not exceed $$$10^5$$$.

Output: For each test case print a single integer — the smallest number of additional stages required for your result to be able to become greater than or equal to Ilya's result.If your result is already not less than Ilya's result, print $$$0$$$.

Note: In the first test case, you have scored $$$100$$$ points for the first stage, while Ilya has scored $$$0$$$. Thus, your overall result ($$$100$$$) is already not less than Ilya's result ($$$0$$$).In the second test case, you have scored $$$0$$$ points for the first stage, while Ilya has scored $$$100$$$. A single stage with an opposite result is enough for both your and Ilya's overall scores to become equal to $$$100$$$.In the third test case, your overall result is $$$30 + 40 + 50 = 120$$$, while Ilya's result is $$$100 + 100 + 100 = 300$$$. After three additional stages your result might become equal to $$$420$$$, while Ilya's result might become equal to $$$400$$$.In the fourth test case, your overall result after four additional stages might become equal to $$$470$$$, while Ilya's result might become equal to $$$400$$$. Three stages are not enough.

Sample Inputs:
5
1
100
0
1
0
100
4
20 30 40 50
100 100 100 100
4
10 20 30 40
100 100 100 100
7
7 59 62 52 27 31 55
33 35 50 98 83 80 64

Sample Outputs:
0
1
3
4
2

Solution (Python):
import sys
import copy
import heapq
import bisect
import functools
from math import *
from collections import defaultdict, Counter, deque
from operator import itemgetter
from itertools import groupby
import itertools
from itertools import accumulate
from decimal import Decimal, ROUND_HALF_UP
readline = lambda : sys.stdin.readline().rstrip('\r\n')

def solve():
    n = int(readline())
    a = [0] + sorted(list(map(int, readline().split())), reverse=True)
    b = [0] + sorted(list(map(int, readline().split())), reverse=True)
    sa = list(accumulate(a))
    sb = list(accumulate(b))

    def check(mid: int) -> bool:
        tn = mid + n
        k = tn - tn // 4
        sma = 100 * mid + sa[k - mid]
        smb = sb[min(k, n)]
        return sma >= smb
    (l, r) = (0, n)
    while l < r:
        mid = l + r >> 1
        if check(mid):
            r = mid
        else:
            l = mid + 1
    print(r)

def main():
    t = 1
    t = int(readline())
    for i in range(t):
        solve()
if __name__ == '__main__':
    main()

Solution (Python):
def solve(n, a, b):
    b = sorted(b)
    a = sorted(a)
    (pa, pb) = (n // 4, n // 4)
    target = sum(b[pb:])
    myscore = sum(a[pa:])
    add = 0
    while myscore < target:
        n += 1
        add += 1
        if n - 1 - (n - 1) // 4 != n - n // 4:
            myscore += 100
            pb -= 1
            if pb >= 0:
                target += b[pb]
        else:
            myscore += 100 - a[pa]
            pa += 1
    print(add)
for t in range(int(input())):
    n = int(input())
    a = list(map(int, list(input().split())))
    b = list(map(int, list(input().split())))
    solve(n, a, b)

Solution (Python):
case = int(input())
for i in range(case):
    stage = int(input())
    delete_stage = stage // 4
    my_score_list = list(map(int, input().split(' ')))
    my_score_list = sorted(my_score_list)
    my_sum_forward = sum(my_score_list)
    my_sum = my_sum_forward - sum(my_score_list[:delete_stage])
    his_score_list = list(map(int, input().split(' ')))
    his_score_list = sorted(his_score_list)
    his_sum_forward = sum(his_score_list)
    his_sum = his_sum_forward - sum(his_score_list[:delete_stage])
    if my_sum >= his_sum:
        print(0)
        continue
    else:
        up = 2 * stage
        low = stage + 1
        result = (up + low) // 2
        while low <= up:
            mid = (up + low) // 2
            delete_stage = mid // 4
            my_sum = my_sum_forward + (mid - stage) * 100 - sum(my_score_list[:delete_stage])
            if delete_stage <= mid - stage:
                his_sum = his_sum_forward
            else:
                his_sum = his_sum_forward - sum(his_score_list[:delete_stage - mid + stage])
            if my_sum >= his_sum:
                up = mid - 1
                result = mid
            else:
                low = mid + 1
        print(result - stage)