拿样例举例,我们发现只需要两段备用区间就可以覆盖掉原区间:
思想
我们每次都选最长的一段的备选区间,这样就能用最少的备选区间覆盖原区间:
code
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
typedef pair<int,int> PII;
vector<PII> seg;
bool cmp(PII x , PII y){
return x.second < y.second;
}
int main() {
int st, ed;
cin >> st >> ed;
int n;
cin >> n;
while(n--)
{
PII x;
cin >> x.first>> x.second;
seg.push_back(x);
}
for (int i = 0; i < n; i++) {
PII x;
cin >> x.first >> x.second;
seg.push_back(x);
}
// 按左端点排序
sort(seg.begin(), seg.end(),cmp);
bool is_success = false;
int i = 0, cnt = 0;
while (i < n) {
int rmax = -2e9; // 维护右端点的最大值
while (i < n && seg[i].first<= st) { // 在左端点<=st的区间中,选择右端点最大的一个
rmax = max(rmax , seg[i].second);
i ++;
}
// 如果最大右端点rmax小于st,则没有能覆盖st这个点的区间了,返回false
if (rmax < st) {
is_success = false;
break;
}
else if (rmax >= st) { // 说明[st,rmax]这里面的点被覆盖住了
// 选择右端点最大的那个区间用来覆盖[st,rmax]上的点
st = rmax; //更新start到右端点位置
cnt ++;
if (rmax >= ed) {
is_success = true;
break;
}
}
}
if (is_success == false) cout << -1 << endl;
else cout << cnt << endl;
return 0;
}
注意事项:
我用while循环结果不对,用for循环结果才对: