比賽的時候做這道題的思路跟官方分析的第二種方法一樣,但是少考慮了可以取模來快速計算哪一天,導致大數據超時,好氣。
下面就來看題:
題目簡述
有 個公交路線,必須按順序乘坐,一個人在第 天必須坐完所有路線,也可以在第 天之前完成。用例已確保能在第 天完成。
第 個公交路線每 天運行一次,即只能在 ,, 等等那些天乘坐。同一天可以乘坐多次公交。
但她想儘可能晚地乘坐第一班公交。求最晚從哪一天開始乘坐公交,仍然能在第 天完成旅行。
樣例分析
N = 3
D = 10
X = [3 7 2]
有 3 條路線,需要在 10 天內完成。第一個公交每 3 天跑一次,所以可以是第 3、6、9 天乘坐第一班公交,但是第 9 天坐的話後面兩趟公交就完不成,所以可以從第 6 天開始。
第 7 天剛好是第二趟公交運行週期 7 的倍數,所以第 7 天乘坐第二趟公交。
第 8 天也剛好可以乘坐第 3 趟公交,所以旅行完成。
那麼最晚就可以從第 6 天開始。
解析
可以使用從後向前的方法,在 時間複雜度下解決問題。
使用 表示乘坐的是第 趟公交。
使用 表示乘坐第 趟公交的天數,由於最後一天及之前一定能完成,因此 小於等於最大天數 ,且是 的最大倍數。
又,爲了能夠在第 天及時趕上最後的公交 ,那麼必須要在第 天乘坐第 趟公交。 可以小於等於 且爲 的最大倍數。
這樣倒着算到 也就是第一趟公交時, 也就是要求的最晚出發的天數。
由於 必須是 的倍數,因此計算出的當前的 可能不是 的倍數,可以直接通過計算 得到可以整除的天數。
以一個例子來解釋這個分析:
N = 4
D = 100
X = 11 10 5 50
現在從後向前,取第 100 天完成旅行,那麼後面三趟公交都可以被 100 整除,那麼可以在第 100 天乘坐這三趟公交。
接下來還剩第一趟公交,由於 100 不能整除 11,因此通過上面的公式來計算應該減多少天,100 mod 11 = 1,因此可以在第 99 天乘坐第一趟公交。這樣就得到了答案。
代碼
test_case = int(input().strip())
for t in range(1, test_case + 1):
bus_num, day = list(map(int,input().strip().split()))
route = list(map(int,input().strip().split()))
bus_index = len(route) - 1
while bus_index >= 0:
if day % route[bus_index] == 0: # 計算是否可乘坐公交
bus_index -= 1
else:
day = day - day % route[bus_index] # 如果某天不能乘坐公交,直接將天數計算爲可乘坐公交的天數
print("Case #{}: {}".format(t, day))