比赛的时候做这道题的思路跟官方分析的第二种方法一样,但是少考虑了可以取模来快速计算哪一天,导致大数据超时,好气。
下面就来看题:
题目简述
有 个公交路线,必须按顺序乘坐,一个人在第 天必须坐完所有路线,也可以在第 天之前完成。用例已确保能在第 天完成。
第 个公交路线每 天运行一次,即只能在 ,, 等等那些天乘坐。同一天可以乘坐多次公交。
但她想尽可能晚地乘坐第一班公交。求最晚从哪一天开始乘坐公交,仍然能在第 天完成旅行。
样例分析
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))