week3作业——区间选点

主要思路:
一道贪心的简单应用
将所有的区间进行排序(先按右端点升序;右端点相同按左端点降序)
选点的原则是:

  1. 将(排序后)第一个区间抽出
  2. 选择该区间的右端点
  3. 将包含该区间的右端点的所有区间删去

重复上述操作直至处理完所有的区间

简短的证明

要想使得每个区间上都有点,且只能有一个,使用上述由右至左选区间的策略:如若我们选择最左端点优先的策略进行,那么面临形如(1,4)和 (2,3)的区间时,按左端点升序则会选择1号点,那么(2,3)就无法包括;这只是其中一种造成非最优解的情况。
并且这里选点的策略是取尽量靠近右边界的点,这样选取被满足区间个数会是最大的。

最初我使用了vector的数据结构,每个元素为自己定义的结构体interval。整体思路也没有什么问题,然而连样例都无法通过。在仔细调试后,将问题定位至删除操作的地方。我使用的vector里的erase方法,即传入指向待删除元素的迭代器。
当时vector中仅剩两个元素(区间),删去一个后,会发现之前被删的元素又会重新出现。在仔细阅读stl的文档后,发现还是因为我没有读懂erase方法的功能。
在删除单个的元素后,迭代器指向不会发生变化,仍然指向已经删除的元素,而被删除的元素之后的元素全部向前移动“一格“,这样一来,迭代器指向的是原来被删除元素的下一个元素。至此,bug解决。

具体错误示范:
//想要删掉元素4
vector<int> v{1,2,3,4,5};
for(auto i = v.begin();i != end();i++){
	if(*i==4)
		v.erase(i);  //在将4删去后,4之后的整体想起移动一格
		             //那么i指向了元素5
		             //此时再进行i++的操作就是不合法的
		             //这玩意就叫野指针
}

正确示范:
//想要删掉元素4
vector<int> v{1,2,3,4,5};
for(auto i = v.begin();i != end();){
	if(*i==4)
		v.erase(i);  //即进行了删除操作,就不进行i++
	else
		i++;
}

B - 区间选点

数轴上有 n 个闭区间 [a,b]。
取尽量少的点,使得每个区间内都至少有一个点
不同区间内含的点可以是同一个

Input

第一行1个整数N(N<=100)
第2~N+1行,每行两个整数a,b(a,b<=100)

Output

一个整数,代表选点的数目

Sample Input

    2
    1 5
    4 6

Sample Output

1
  • A Possible Solution
#include<stdio.h>
#include<vector>
#include<algorithm>
using namespace std;

typedef struct tag_interval {
	int l, r;

	tag_interval(int L, int R) {
		l = L;
		r = R;
	}

	bool operator < (const tag_interval& x) {
		if (r == x.r)
			return l < x.l;
		else
			return r > x.r;
	}
}interval;

int main() {
	int n;
	vector<interval> v;
	vector<int> path;
	scanf("%d", &n);
	for (int i = 0; i < n; i++) {
		int l, r;
		scanf("%d %d", &l, &r);
		interval tmp(l, r);
		v.push_back(tmp);
	}
	sort(v.begin(),v.end()); 
	while(!v.empty()){
		interval tmp=v.back();
		int p=tmp.r;
		v.pop_back();
		path.push_back(p);
		for(auto i=v.begin();(!v.empty()) && (i!=v.end());){
			if(p>=i->l && p<=i->r){
				v.erase(i);
			}
			else{
				i++;
			}
		}
	}
	printf("%d\n",path.size());
	return 0;
}
发布了11 篇原创文章 · 获赞 0 · 访问量 129

猜你喜欢

转载自blog.csdn.net/weixin_43669888/article/details/104810458
今日推荐