雑記です
2025-10-05
type I = [[Int]]
type O = [[Int]]
solve :: I -> O
solve ([n]:xs:[q]:ys) = map (singleton . f) (concat ys)
where
ary = listArray (0,n-1) $ sort xs :: Array Int Int
f b | idx == 0 = d
| otherwise = min d d0
where
idx = lowerBound (ary!) (-1) (n-1) b
idx0 = idx - 1
d = abs (b - ary!idx)
d0 = abs (b - ary!idx0)
Aiの列を昇順にソートした後に、各BjでAiの列を二分探索して、Ai>=Bjとなる最小のAiを求める。|Ai-Bj|と|A{i-1}-Bj|の小さいほうが、生徒jの不満度の最小値になる。
lowerBound :: Ord a => (Int -> a) -> Int -> Int -> a -> Int
lowerBound f lb ub x
| ub - lb > 1 = if f mid >= x
then lowerBound f lb mid x
else lowerBound f mid ub x
| otherwise = ub
where
mid = (lb + ub) `div` 2
蟻本を参考に二分探索を追加した。探索範囲が(lb, ub]
なのが今一つな気がする。今後探索範囲を[lb,ub)
に変更したラッパーを書くかも。