演習課題「k番目の値」
整数n,m,kと長さnの配列a,長さmの配列bが与えられるので、各i,jに対してa[i]-b[j]で表される合計n×m個の整数のうち、小さい方からk番目の値を求めてください。
すでに入力を行うコードと関数lower_bound,upper_boundが実装されているので、コードを書き足して完成させてください。
期待する出力値
-3
#07:数列のk番目
このチャプターでは、レベルアップ問題集「二分探索メニュー」の「長い長い数列」の問題を解いていきます。
def lower_bound(a, n, x):
    left, right = 0, n
    while left != right:
        mid = (left + right) // 2
        if a[mid] >= x:
            right = mid
        else:
            left = mid + 1
    return left
def upper_bound(a, n, y):
    left, right = 0, n
    while left != right:
        mid = (left + right) // 2
        if a[mid] > y:
            right = mid
        else:
            left = mid + 1
    return left
n = int(input())
a = [int(x) for x in input().split()]
m = int(input())
b = [int(x) for x in input().split()]
k = int(input())
# 配列(リスト)bを昇順にソート
b.sort()
# 変数left,rightをそれぞれ-1と2000000000で初期化
left, right = -1, 2000000000
# leftとrightの差が1でない間
while right-left != 1:
    # 変数midに(left+right)/2を代入
    mid = (left + right) // 2
    # 個数を表す変数countを0で初期化
    count = 0
    # iを0からn-1まで繰り返す
    for i in range(n):
        # upper_bound(b,m,a[i]+mid)-lower_bound(b,m,a[i]-mid)をcountに加算
        count += upper_bound(b, m, a[i]+mid) - lower_bound(b, m, a[i]-mid)
    # もしcountがk以上なら
    if count >= k:
        # rightをmidで更新
        right = mid
    # そうでなければ
    else:
        # leftをmidで更新
        left = mid
# rightを出力
print(right)
6
1 2 3 4 5 6
6
1 2 3 4 5 6
6
6
1 2 3 4 5 6
6
1 2 3 4 5 6
7