Description
我们定义一个整数区间[a,b]:是一个从a开始至b 结束的连续整数的集合。编一个程序,对给定的 n(n≤1000
)个区间,找出满足下述条件的所含元素个数最少的集合中元素的个数:对于所给定的每一个区间,都至少有两个
不同的整数属于该集合。
Input
第一行一个正整数n,接下来有n行,每行给定一个区间的a,b值。
Output
一个正整数,满足条件的集合所包含的最少元素个数
Sample Input
4 3 6 2 4 0 2 4 7
Sample Output
4 //选取[1,2,4,6]这四个元素
分析
这道题可以用一个贪心的思路
首先以每个区间的右端点将所有区间进行排序
然后将第一个区间的最右端两个元素加入目标集合
枚举下一个区间
如果当前区间没有元素在目标集合中,将该区间最右端两个元素加入集合
如果当前区间有一个元素在目标集合中 且 不是最右端元素,将该区间最右端元素加入集合
如果当前区间有一个元素在目标集合中 且 是最右端元素,将该区间从右往左第二个元素加入集合
如果当前区间有两个元素在目标集合中,枚举下一个区间
代码
#include<bits/stdc++.h>
using namespace std;
struct node {
int l, r;
node () {}
node (int ll, int rr) {
l = ll;
r = rr;
}
};
inline int read() {
int x = 0, f = 1; char ch = getchar();
while (ch < '0' || ch > '9') {if (ch == '-') f = -1; ch = getchar();}
while (ch >= '0' && ch <= '9') {x = (x << 1) + (x << 3) + (ch ^ 48); ch = getchar();}
return x * f;
}
bool cmp(node a, node b) {
return a.r < b.r;
}
int main() {
int n = read();
vector<node> v(n);
vector<int> ans;
for (int i = 0; i < n; i++) {
cin >> v[i].l >> v[i].r;
}
sort(v.begin(), v.end(), cmp);
for (int i = 0; i < n; i++) {
int num = 0;
bool flag = 0;
for (int j = v[i].l; j <= v[i].r; j++) {
if (find(ans.begin(), ans.end(), j) != ans.end()) {
num++;
if (*find(ans.begin(), ans.end(), j) == v[i].r) {
flag = 1;
}//是最右端元素
}
}
if (!num) {
ans.push_back(v[i].r);
ans.push_back(v[i].r - 1);
}
else if (num == 1 && !flag) {
ans.push_back(v[i].r);
}
else if (num == 1 && flag) {
ans.push_back(v[i].r - 1);
}
}
printf("%d", ans.size());
return 0;
}