题意:找出最小的集合,使他满足给定的各个区间内至少有两个点被包括。
思路:和之前做过的那道雷达站问题非常类似,区间选点,不过每个区间要有两个点,而且区间是离散的为整数。回忆一下之前的区间选点,是拿区间的右端点作为标记与后面的区间进行比较,也就是可以认为每次选的点都是右端点。在这里由于要选两个点,自然可以想到可以取区间倒数两个点作为标记。
每次比较时分情况讨论:①两标记点均在区间内,无需变化。
②有一点在,一个不在,说明需在当前区间内再取一个点,自然是取右端点,更新两标记点。
③都不在,说明需在当前区间内取两个点,取倒数两个点,更新两标记点。
代码:
#include <iostream>
#include <fstream>
#include <algorithm>
using namespace std;
struct node {
int l, r;
}nodes[10010];
bool cmp(node a, node b)
{
return a.r < b.r || (a.r == b.r&&a.l < b.l);
}
int main()
{
//fstream cin("test.txt");
int n;
cin >> n;
for (int i = 0; i < n; i++)
{
cin >> nodes[i].l >> nodes[i].r;
}
sort(nodes, nodes + n, cmp);
int ans = 2;
int tmp1 = nodes[0].r - 1;
int tmp2 = nodes[0].r;
for (int i = 1; i < n; i++)
{
if (tmp1 >= nodes[i].l)
continue;
else
{
if (tmp2 >= nodes[i].l)
{
ans++;
tmp1 = tmp2;
tmp2 = nodes[i].r;
}
else
{
ans += 2;
tmp1 = nodes[i].r - 1;
tmp2 = nodes[i].r;
}
}
}
cout << ans << endl;
//system("pause");
return 0;
}