【题目链接】
ybt 1236:区间合并 OpenJudge 2.4 7620:区间合并
【题目考点】
1. 贪心
2. 排序
【解题思路】
解法1. 贪心
将所有区间按左端点从小到大排序。 由于区间数量达到
5
?
1
0
4
5*10^4
5?104,因此只能用复杂度为
O
(
n
l
o
g
n
)
O(nlogn)
O(nlogn)的排序方法。 设所有区间合并在一起的总区间为
[
l
m
,
r
m
]
[l_m, r_m]
[lm?,rm?],排序后第i区间为
[
l
i
,
r
i
]
[l_i, r_i]
[li?,ri?]。初始情况,下
l
m
=
l
i
,
r
m
=
r
i
l_m=l_i, r_m=r_i
lm?=li?,rm?=ri? 顺序取每个区间,假设取到的第i区间为
[
l
i
,
r
i
]
[l_i, r_i]
[li?,ri?],尝试将取到的区间和前面所有区间构成的总区间
[
l
m
,
r
m
]
[l_m, r_m]
[lm?,rm?]进行合并
- 如果
l
i
≤
r
m
l_i \le r_m
li?≤rm?,那么二者可以合并,合并后,如果
r
i
>
r
m
r_i > r_m
ri?>rm?,那么
r
m
=
r
i
r_m=r_i
rm?=ri?
- 如果
l
i
>
r
m
l_i > r_m
li?>rm?,那么二者不可以合并。其余的区间的左端点都大于等于
l
i
l_i
li?,都无法和前各面区间合并成的区间
[
l
m
,
r
m
]
[l_m, r_m]
[lm?,rm?]合并,因此最终无法合并成一个闭区间。
重复上述过程,如果最后所有区间都成功合并,就输出
l
m
l_m
lm?与
r
m
r_m
rm?,否则输出no。
【题解代码】
解法1:贪心
#include<bits/stdc++.h>
using namespace std;
#define N 50005
struct Pair
{
int l, r;
}a[N];
bool cmp(Pair a, Pair b)
{
return a.l < b.l;
}
int main()
{
int n;
Pair pm;
cin >> n;
for(int i = 1; i <= n; ++i)
cin >> a[i].l >> a[i].r;
sort(a+1, a+1+n, cmp);
pm = a[1];
for(int i = 2; i <= n; ++i)
{
if(a[i].l <= pm.r)
pm.r = max(a[i].r, pm.r);
else
{
cout << "no";
return 0;
}
}
cout << pm.l << ' ' << pm.r;
return 0;
}
#include<bits/stdc++.h>
using namespace std;
#define N 50005
struct Pair
{
int l, r;
bool operator < (const Pair &b) const
{
return l < b.l;
}
}a[N];
int main()
{
int n;
Pair pm;
cin >> n;
for(int i = 1; i <= n; ++i)
cin >> a[i].l >> a[i].r;
sort(a+1, a+1+n);
pm = a[1];
for(int i = 2; i <= n; ++i)
{
if(a[i].l <= pm.r)
pm.r = max(a[i].r, pm.r);
else
{
cout << "no";
return 0;
}
}
cout << pm.l << ' ' << pm.r;
return 0;
}
|