给定的N个由两个非负整数L和R表示的段(或范围)。将这些段划分为两个非空的组,这样就不会有来自不同组的两个段共享同一点。如果可能的话,请从集合{1,2}中为每个段分配一个数字,否则打印“不可能” 。
例子:
Input: arr[][] = {{5, 5}, {2, 3}, {3, 4}}
Output: 2 1 1
Since 2nd and 3rd segment have one point common i.e. 3, they should be contained in same group.
Input: arr[][] = {{3, 5}, {2, 3}, {1, 4}}
Output: Not Possible
All segments should be contained in the same group since every pair has a common point with each other. Since the other group is empty, answer is not possbile.
先决条件:合并重叠间隔
方法:使用合并重叠间隔的概念,我们可以将相同的组分配给所有重叠的段,然后更改组号。
要合并重叠的段,请按照段的原始索引的顺序,按照它们的正确索引对所有段进行排序。然后,遍历这些段并检查前一个段是否与当前段重叠。如果确实合并,则将其合并为一个细分,如果未创建新细分,则将其合并。
最后,检查组中是否有一个没有空。如果其中之一为空,则无法回答,否则将打印所有分配的段值。
下面是上述方法的实现:
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是段数