查找最少的积分数以覆盖所有细分市场

发布于 2025-01-22 07:26:32 字数 2136 浏览 0 评论 0原文

嗨,我有一个问题如下:

给定一组N段{[A0,B0],[A1,B1],。 。 。 ,[an-1,bn-1]}在一条线上的整数坐标,找到最小数字m的点m,使每个段至少包含一个点。也就是说,找到一组最小尺寸的整数x,以便对于任何段[ai,bi]都有一个点x∈X,以便ai≤x≤bi。

输入格式:输入的第一行包含段的数字n。以下n行中的每条线都包含两个整数AI和BI(由空间隔开),以定义第i-th段的端点的坐标。

输出格式:在第一行上输出最小数字m和M点的整数坐标(被空间隔开)。您可以按任何顺序输出点。如果有很多这样的点,则可以输出任何集合。 (不难看到总是存在一组最小尺寸的点,以使这些点的所有坐标都是整数。)

Sample 1:
Input: 3
1 3
2 5
3 6
Output: 1 3
Explanation:
In this sample, we have three segments: [1,3],[2,5],[3,6] (of length 2,3,3 respectively). All of them contain the point with coordinate 3: 1 ≤3 ≤3, 2 ≤3 ≤5, 3 ≤ 3 ≤ 6.
Sample 2:
Input: 4
4 7
1 3
2 5
5 6
Output: 2
3 6

说明: 第二和第三个段包含坐标3的点,而第一个和第四段包含坐标6的点。由于段[1,3]和[5,[5, 6]是不相交的。

解决方案: 贪婪的选择是选择最小右端点。然后删除所有包含端点的段。 继续选择最小的右端点并删除段

我遵循解决方案。我找到了最小右端点,删除了我代码中包含该端点的所有段。然后使用新的片段列表再次执行该功能(继续选择最小的正确端点和删除片段 - 递归),但我遵守代码的顺序,无法使其可行。

list_time = [[4,7],[1,3],[2,5],[5,6]]

def check_inside_range(n, lst): #Function to check if a number is inside the range of start and end of a list
#for example 3 is in [3,5], 4 is not in [5,6], return False if in
    if lst[1]-n>=0 and n-lst[0]>=0:
        return False
    else:
        return True
def lay_chu_ki(list_time):

    list_time.sort(key = lambda x: x[1]) #Sort according to the end of each segments [1,3],[2,5],[5,6],[4,7]
    first_end = list_time[0][1] #Selecting the minimum right endpoint
    list_after_remove = list(filter(lambda x: check_inside_range(first_end, x),list_time))
    #Remove all segments that contains that endpoint

    lay_chu_ki(list_after_remove) #Keep doing the function again with new segments list
                                  #(Keep choosing minimum right endpoint and removing segments)

    return first_end #I don't know where to put this line.

print(lay_chu_ki(list_time))

如您所见,我已经完成了3个步骤:选择最小右端点删除所有包含端点的段; 继续选择最小的正确端点并删除段,但它无法以某种方式起作用。我试图首先打印两个数字3和6(每个递归调用的返回结果)。我还尝试创建一个count变量来计算每个递归调用(count += 1),但由于它重置count = 0 <) /代码>对于每个呼叫。

Hi I have a problem as below:

Given a set of n segments {[a0, b0], [a1, b1], . . . , [an-1, bn-1]} with integer coordinates on a line, find the minimum number m of points such that each segment contains at least one point. That is, find a set of integers X of the minimum size such that for any segment [ai,bi] there is a point x ∈ X such that ai ≤ x ≤ bi.

Input Format: The first line of the input contains the number n of segments. Each of the following n lines contains two integers ai and bi (separated by a space) defining the coordinates of endpoints of the i-th segment.

Output Format: Output the minimum number m of points on the first line and the integer coordinates of m points (separated by spaces) on the second line. You can output the points in any order. If there are many such sets of points, you can output any set. (It is not difficult to see that there always exist a set of points of the minimum size such that all the coordinates of the points are integers.)

Sample 1:
Input: 3
1 3
2 5
3 6
Output: 1 3
Explanation:
In this sample, we have three segments: [1,3],[2,5],[3,6] (of length 2,3,3 respectively). All of them contain the point with coordinate 3: 1 ≤3 ≤3, 2 ≤3 ≤5, 3 ≤ 3 ≤ 6.
Sample 2:
Input: 4
4 7
1 3
2 5
5 6
Output: 2
3 6

Explanation:
The second and the third segments contain the point with coordinate 3 while the first and the fourth segments contain the point with coordinate 6. All the four segments cannot be covered by a single point, since the segments [1, 3] and [5, 6] are disjoint.

Solution:
The greedy choice is selecting the minimum right endpoint. Then remove all segments that contains that endpoint. Keep choosing minimum right endpoint and removing segments.

I followed the solution. I found the minimum right endpoint, removed all segments that contain that endpoint in my code. Then execute the function again with the new segments list (Keep choosing minimum right endpoint and removing segments - Recursive) but I'm stuck with the order of my code and can't make it works.

list_time = [[4,7],[1,3],[2,5],[5,6]]

def check_inside_range(n, lst): #Function to check if a number is inside the range of start and end of a list
#for example 3 is in [3,5], 4 is not in [5,6], return False if in
    if lst[1]-n>=0 and n-lst[0]>=0:
        return False
    else:
        return True
def lay_chu_ki(list_time):

    list_time.sort(key = lambda x: x[1]) #Sort according to the end of each segments [1,3],[2,5],[5,6],[4,7]
    first_end = list_time[0][1] #Selecting the minimum right endpoint
    list_after_remove = list(filter(lambda x: check_inside_range(first_end, x),list_time))
    #Remove all segments that contains that endpoint

    lay_chu_ki(list_after_remove) #Keep doing the function again with new segments list
                                  #(Keep choosing minimum right endpoint and removing segments)

    return first_end #I don't know where to put this line.

print(lay_chu_ki(list_time))

As you can see, I've already done 3 steps: Selecting the minimum right endpoint; Remove all segments that contains that endpoint; Keep choosing minimum right endpoint and removing segments but it won't work somehow. I tried to print two numbers 3 and 6 first (the return result of each recursive call). I also tried to create a count variable to count each recursive call (count +=1) but it didn't work too since it reset count = 0 for each call.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

誰ツ都不明白 2025-01-29 07:26:32

我认为递归使实施过于复杂。尽管仍然可行,但您必须传递大量额外的参数,这可能很难跟踪。我认为,迭代实施这种方法要简单得多。

另外,您的方法反复使用filter()list(),每次执行时需要线性时间(澄清,“线性”表示线性的线性输入列表)。在最坏的情况下,您将为列表中的每个元素执行该操作,这意味着原始实现的运行时是二次的(假设您将代码解决了现有问题)。通过单个通过列表,这种方法可以避免这种方法:

def lay_chu_ki(list_time):
    list_time.sort(key=lambda x: x[1])
    idx = 0
    selected_points = []
    
    while idx != len(list_time):
        selected_point = list_time[idx][1]
        
        while idx != len(list_time) and list_time[idx][0] <= selected_point:
            idx += 1
        
        selected_points.append(selected_point)
    
    return selected_points
        

result = lay_chu_ki(list_time)
print(len(result))
print(' '.join(map(str, result)))

在给定列表的情况下,输出:

2
3 6

I think recursion overcomplicates the implementation. While it's still feasible, you have to pass in a bunch of extra parameters, which could be difficult to track. In my opinion, it's much simpler to implement this approach iteratively.

Also, your approach repeatedly uses filter() and list(), which takes linear time every time you do it (to clarify, "linear" means linear in the size of the input list). In the worst case, you would perform that operation for every element in the list, which means that the runtime of your original implementation is quadratic (assuming you fix the existing issues with your code). This approach avoids that by making a single pass through the list:

def lay_chu_ki(list_time):
    list_time.sort(key=lambda x: x[1])
    idx = 0
    selected_points = []
    
    while idx != len(list_time):
        selected_point = list_time[idx][1]
        
        while idx != len(list_time) and list_time[idx][0] <= selected_point:
            idx += 1
        
        selected_points.append(selected_point)
    
    return selected_points
        

result = lay_chu_ki(list_time)
print(len(result))
print(' '.join(map(str, result)))

With the given list, this outputs:

2
3 6
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文