我正在尝试练习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()))
任何提示将不胜感激!
您的方法可能适用于大多数测试用例,但是有些极端的情况会证明它是错误的。试试这个测试用例,您将理解为什么失败:
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
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句