我正在尝试练习Google Kick Start,并解决Metal Harvest Task:
您负责部署机器人以从附近的小行星上收获Kickium。机器人的设计目的不是为了团队协作,因此在任何时间点只能收获一个机器人。在返回校准之前,单个机器人可以连续部署多达K个时间单位,无论在这段时间内花费多少时间进行收获。收获只能在特定的时间间隔内进行。这些时间间隔不重叠。在给定K和允许收获的时间间隔的情况下,在所有可能的时间收获最少需要部署多少个机器人?
我阅读了分析并得到了结果,但是我不明白为什么我的解决方案不起作用。提交时,我总是会收到“ WA”-错误的答案。
主要思想是,我首先对时间间隔进行排序,然后将其分为多个块,其中一个块中的所有间隔之间的时间步长少于K然后,在一个块中,我每K步连续部署机器人,即每个块需要math.ceil(chunk_len / K)
个机器人。我不需要大块之间的机器人。
从概念上讲,对吧?它也通过了我的测试用例。 所以我猜,关于列表索引或边缘情况我有一些错误,但我不知道是什么。
import math
class Interval:
def __init__(self, start, end):
self.start = start
self.end = end
class Solution:
def __init__(self, max_time, intervals):
self.max_time = max_time
self.intervals = intervals
def harvest_v1(self):
"""start harvesting and return min number of robots"""
num_robots = 0
# sort intervals with increasing start time --> O(N log(N))
sorted_intervals = sorted(self.intervals, key=lambda interval: interval.start)
# walk through intervals, starting at --> O(N)
chunk_start = sorted_intervals[0].start
for i in range(1, len(sorted_intervals)):
# calc duration to next interval and stop chunk if there's K or more time until the next interval
time_to_next = sorted_intervals[i].start - sorted_intervals[i-1].end
if time_to_next >= self.max_time:
# then stop chunk and compute num robots needed for chunk
chunk_len = sorted_intervals[i-1].end - chunk_start
num_robots += math.ceil(chunk_len / self.max_time)
# start a new chunk
chunk_start = sorted_intervals[i].start
# then still include last interval
chunk_len = sorted_intervals[-1].end - chunk_start
num_robots += math.ceil(chunk_len / self.max_time)
return num_robots
# read input and generate output
num_tests = int(input())
for test in range(1, num_tests + 1):
num_intervals, max_time = [int(k) for k in input().split()]
intervals = []
for interval in range(num_intervals):
start, end = [int(k) for k in input().split()]
intervals.append(Interval(start, end))
sol = Solution(max_time, intervals)
print("Case #{}: {}".format(test, sol.harvest_v1()))
任何提示将不胜感激!
答案 0 :(得分:1)
您的方法可能适用于大多数测试用例,但有些极端情况可能会证明它是错误的。 试试这个测试用例,您将理解为什么失败:
max_time = 6
intervals = [Interval(1,3), Interval(4,7), Interval(11,16), Interval(17,22)]
正确的输出:3
您的程序输出:4
说明
您的代码标记chunk start = start of the first interval
并向前循环,直到找到与前一个间隔>= max_time
有时间间隔的间隔为止。它使用循环中当前间隔的robot deployments
和chunk start
计算到该间隔所需的end time
。由于您的代码仅处理time_to_next >= self.max_time
条件,因此相反的条件将成为问题。
在我前面提到的测试用例中,您的代码会将所有间隔放入单个块中,因为所有间隔之间的时间间隔小于max_time
,但是最佳解决方案是将其间隔为2或3块。
如果您想尝试其他方法,请查看以下代码:
def harvest_v1(self):
sorted_intervals = sorted(self.intervals, key=lambda interval: interval.start)
robots_deployed = 0 # Keeps track of total robots deployed
next_calibration_time = 0 # Keeps track of time for next robot calibration
for interval in sorted_intervals:
start_i = interval.start
end_i = interval.end
interval_duration = end_i - start_i
if next_calibration_time <= start_i: # If no robot has been deployed yet
# or previous robot has been sent for calibration, then
# calculate the number of deployments required for current interval
deployments_required = math.ceil(interval_duration / self.max_time)
robots_deployed += deployments_required
# calculate and track the time at which lastly deployed robot will be sent for calibration
next_calibration_time = start_i + (deployments_required * self.max_time)
elif next_calibration_time < end_i: # If some robot is still working then
# calculate the time remaining in current interval after currently working robot becomes unavailable
remaining_duration = end_i - next_calibration_time
# calculate the number of deployments required
deployments_required = math.ceil(remaining_duration / self.max_time)
robots_deployed += deployments_required
# calculate and track the time at which lastly deployed robot will be sent for calibration
next_calibration_time = next_calibration_time + (deployments_required * self.max_time)
return robots_deployed