📌  相关文章
📜  将N个分段分为两个非空组,以便满足给定条件

📅  最后修改于: 2021-04-29 01:37:56             🧑  作者: Mango

给定的N个由两个非负整数LR表示的段(或范围)。将这些段划分为两个非空的组,这样就不会有来自不同组的两个段共享同一点。如果可能的话,请从集合{1,2}中为每个段分配一个数字,否则打印“不可能”

例子:

先决条件:合并重叠间隔

方法:使用合并重叠间隔的概念,我们可以将相同的组分配给所有重叠的段,然后更改组号。
要合并重叠的段,请按照段的原始索引的顺序,按照它们的正确索引对所有段进行排序。然后,遍历这些段并检查前一个段是否与当前段重叠。如果确实合并,则将其合并为一个细分,如果未创建新细分,则将其合并。
最后,检查组中是否有一个没有空。如果其中之一为空,则无法回答,否则将打印所有分配的段值。

下面是上述方法的实现:

C++
// CPP Program to divide N segments into
// two non empty groups such that given
// condition is satisfied
#include 
using namespace std;
  
// Structure to hold the elements of
// a segment
struct segment {
  
    // left index
    int l;
  
    // right index
    int r;
  
    // index of the segment
    int idx;
};
  
// Comparator function to sort the segments
// according to the right indexes
bool comp(const segment& a, const segment& b)
{
    if (a.r == b.r)
        return a.idx < b.idx;
    return a.r < b.r;
}
  
// Function to print the answer if it exists
// using the concept of merge overlapping segments
void printAnswer(vector > v, int n)
{
    segment seg[n];
  
    // Assigning values from the vector v
    for (int i = 0; i < n; i++) {
        seg[i].l = v[i].first;
        seg[i].r = v[i].second;
        seg[i].idx = i;
    }
  
    // Sort the array of segments
    // according to right indexes
    sort(seg, seg + n, comp);
  
    // Resultant array
    int res[n];
    memset(res, 0, sizeof(res));
  
    // Let's denote first group with 0 and second
    // group with 1
    // Current segment
    int prev = 0;
  
    // Assigning group 1 to first segment
    res[seg[prev].idx] = 0;
    for (int i = 1; i < n; i++) {
  
        // If the current segment overlaps
        // with the previous segment, merge it
        if (seg[i].l <= seg[prev].r) {
  
            // Assigning same group value
            res[seg[i].idx] = res[seg[prev].idx];
            seg[prev].r = max(seg[prev].r, seg[i].r);
        }
        else {
  
            // Change group number and create
            // new segment
            res[seg[i].idx] = res[seg[prev].idx] ^ 1;
            ++prev;
            seg[prev] = seg[i];
        }
    }
  
    // Check if one of the groups is empty or not
    int one = 0, two = 0;
    for (int i = 0; i < n; i++) {
        if (!res[i])
            one++;
        else
            two++;
    }
  
    // If both groups are non-empty
    if (one && two) {
        for (int i = 0; i < n; i++)
            cout << res[i] + 1 << " ";
        cout << endl;
    }
    else
        cout << "Not Possible" << endl;
}
  
// Driver Code
int main()
{
    vector > v = { { 1, 2 }, { 3, 4 }, { 5, 6 } };
    int n = v.size();
    printAnswer(v, n);
    return 0;
}


Python3
# Python3 Program to divide N segments 
# into two non empty groups such that 
# given condition is satisfied 
  
# Structure to hold the elements of 
# a segment 
class segment: 
  
    def __init__(self):
        self.l = None # left index
        self.r = None # right index
        self.idx = None # index of the segment
      
# Function to print the answer if
# it exists using the concept of
# merge overlapping segments 
def printAnswer(v, n): 
  
    seg = [segment() for i in range(n)] 
  
    # Assigning values from the vector v 
    for i in range(0, n): 
        seg[i].l = v[i][0] 
        seg[i].r = v[i][1] 
        seg[i].idx = i 
  
    # Sort the array of segments 
    # according to right indexes 
    seg.sort(key = lambda x: (x.r, x.idx))
      
    # Resultant array 
    res = [0] * (n) 
      
    # Let's denote first group with 0 and
    # second group with 1 Current segment 
    prev = 0
  
    # Assigning group 1 to first segment 
    res[seg[prev].idx] = 0
    for i in range(1, n): 
  
        # If the current segment overlaps 
        # with the previous segment, merge it 
        if seg[i].l <= seg[prev].r: 
  
            # Assigning same group value 
            res[seg[i].idx] = res[seg[prev].idx] 
            seg[prev].r = max(seg[prev].r, seg[i].r) 
          
        else:
  
            # Change group number and create 
            # new segment 
            res[seg[i].idx] = res[seg[prev].idx] ^ 1
            prev += 1
            seg[prev] = seg[i] 
  
    # Check if one of the groups is 
    # empty or not 
    one, two = 0, 0
    for i in range(0, n): 
        if not res[i]:
            one += 1
        else:
            two += 1
      
    # If both groups are non-empty 
    if one and two: 
        for i in range(0, n): 
            print(res[i] + 1, end = " ") 
        print() 
      
    else:
        print("Not Possible") 
  
# Driver Code 
if __name__ == "__main__":
  
    v = [[1, 2], [3, 4], [5, 6]] 
    n = len(v) 
    printAnswer(v, n) 
  
# This code is contributed 
# by Rituraj Jain


输出:
1 2 1

时间复杂度: O(n * log n),其中n是段数