このシリーズではレッドコーダーが教える、競プロ・AtCoder上達のガイドライン【中級編:目指せ水色コーダー!】でまとめられている100問をPythonで解いています。
問題
ポイント
この問題は二分探索を用いて解いていきます。(Pythonではbisectを使うと便利です。)
①配達先の場所を店舗リスト内で二分探索する。
②配達先の左右の店舗の内、近い方から配達する。
といった流れで解答を求めていきます。
コード
def main():
import sys
import bisect
sys.setrecursionlimit(10 ** 6) #再帰関数の上限を上げる。今回は特に必要ないがおまじない。
input = sys.stdin.readline
d = int(input()) # 環状線の全長
n = int(input()) # 店舗の個数
m = int(input()) # 注文の個数
# 店舗のリストを作成
stores = [0]
for _ in range(n - 1):
stores.append(int(input()))
stores.sort()
# 配達先のリストを作成
destinations = []
for _ in range(m):
destinations.append(int(input()))
# ①配達先の場所を店舗リスト内で二分探索する。②配達先の左右の店舗の内、近い方から配達する。
sum_distance = 0
for dt in destinations:
i = bisect.bisect(stores, dt)
if i == len(stores): # 配達先の場所が1番最後の店舗と本店の間の場合
if abs(dt - stores[-1]) < abs(dt - d): # 1番最後の店舗と本店からの距離を比較
sum_distance += abs(dt - stores[-1])
else:
sum_distance += abs(dt - d)
else:
if abs(dt - stores[i-1]) < abs(dt - stores[i]): # 左右の店舗からの距離を比較
sum_distance += abs(dt - stores[i-1])
else:
sum_distance += abs(dt - stores[i])
print(sum_distance)
if __name__ == '__main__':
main()