uva10020 - Minimal coverage(区间覆盖)

题目:uva10020 - Minimal coverage(区间覆盖)

题目大意:给出一些线段,然后问怎样取能使得最少的线段覆盖区间[0, M].

解题思路:先预处理掉那些和区间【0,M】不沾边的线段。

将线段按照起点小的排序。

接着遍历这些线段。首先先判断起点最小的点是否<=0,如果不满足这个说明它不能覆盖区间。

然后每次都小于等于当前覆盖的起点的最长线段,之后要将起点更新成这个最长线段的终点。然后接着判断下一条线段。如果更新了起点发现依然找不到满足条件的线段,说明不能覆盖。

最后还要看一下是否能够覆盖到M。

代码:

#include <stdio.h>
#include <algorithm>
#include <string.h>
using namespace std;

const int N = 100005;
int m, n;
int visit[N];

struct segments {

	int l, r;
}s[N];

int cmp (const segments& a, const segments &b) { return a.l < b.l; }

int Max (const int a, const int b) {return a > b ? a: b;}

int solve () {

	memset (visit, 0, sizeof (visit));
	if (s[0].l > 0)             //判断能否覆盖区间起点
		return 0;
	int st = 0;
	int ll = -1;
	int t = -1;
	for (int i = 0; i < n; i++) {

		if (s[i].l <= st) {  //找符合条件的最长的线段

			if (ll < s[i].r) {

				visit[i] = 1;
				if (t >= 0)
					visit[t] = 0;
				t = i;
				ll = Max (ll, s[i].r);
			}
		} else {           

			if (st == ll)  //更新后发现依然没有
				return 0;
			st = ll;       <span style="font-family: Arial, Helvetica, sans-serif;">//更新起点</span>

			i--;
			t = -1;        //更新起点后这个记录之前记录的线段就是确定需要,和更新后的没有关联了
		}
		if (ll >= m)           //能否覆盖终点
			break;
	}
	if (ll < m)                     <span style="font-family: Arial, Helvetica, sans-serif;">//能否覆盖终点</span>

		return 0;
	int count = 0;
	for (int i = 0; i < n; i++)
		if (visit[i])
			count++;
	return count;
}

int main () {

	int t;
	int l, r;
	scanf ("%d", &t);
	while (t--) {

		scanf ("%d", &m);
		n = 0;
		while (scanf ("%d%d", &l, &r), l || r) {

			if (r <= 0 || l >= m)
				continue;
			s[n].l = l;
			s[n].r = r;
			n++;
		}

		sort (s, s + n, cmp);
		int count = solve();
		printf ("%d\n", count);
		if (count) {
			for (int i = 0; i < n; i++)
				if (visit[i])
					printf ("%d %d\n", s[i].l, s[i].r);
		}
		if (t)
			printf ("\n");
	}
	return 0;
}
时间: 2024-10-04 05:14:02

uva10020 - Minimal coverage(区间覆盖)的相关文章

ural Minimal Coverage (区间覆盖)

http://acm.timus.ru/problem.aspx?space=1&num=1303 给出一些区间,选择尽量少的区间能覆盖到[0,m]. 小白p154,典型的区间覆盖问题.一直在想怎么dp.. 首先预处理,先按左端点从小到大排序,若左端点相同右端点从大到小排序,若区间x完全包含y,按照贪心的思想,y是没有意义的,有大区间可以选何必选择小区间.处理完事之后各个区间满足a1 <= a2 <= a3....且b1 <= b2 <= b3... 这样找到第一个覆盖0的

区间选点+区间覆盖

区间选点+区间覆盖 区间选点问题(选择最少的点,使得每个区间都至少有k个点) 将这些区间[l,r]先按照r从小到大排序,再按照l从大到小排序.选点尽量选择靠近右边界的点.然后按照这个排序后的区间进行遍历,用一个变量来存放遍历过程中上个区间的右边界,然后碰到一个新的区间的时候需要分两种情况讨论:1.这个区间和上个区间有相交的部分,那么就需要判断一下上次选择的点有多少在这个区间内,这些点满足要求吗?不满足的话还需要在这个区间内选点2.这个区间和上个区间没有交集,那么这个区间就需要选点. 上述策略可以

uva 10020 Minimal coverage 【贪心】+【区间完全覆盖】

Minimal coverage The Problem Given several segments of line (int the X axis) with coordinates [Li,Ri]. You are to choose the minimal amount of them, such they would completely cover the segment [0,M]. The Input The first line is the number of test ca

【区间覆盖问题】uva 10020 - Minimal coverage

可以说是区间覆盖问题的例题... Note: 区间包含+排序扫描: 要求覆盖区间[s, t]; 1.把各区间按照Left从小到大排序,如果区间1的起点大于s,则无解(因为其他区间的左起点更大):否则选择起点在s的最长区间; 2.选择区间[li, ri]后,新的起点应更新为ri,并且忽略所有区间在ri之前的部分:  Minimal coverage  The Problem Given several segments of line (int the X axis) with coordinat

UVa 10020 (最小区间覆盖) Minimal coverage

题意: 数轴上有n个闭区间[ai, bi],选择尽量少的区间覆盖一条指定线段[0, m] 算法: [start, end]为已经覆盖到的区间 这是一道贪心 把各个区间先按照左端点从小到大排序,更新start为end,如果区间1在start的右端,则无解,因为其他区间更不可能覆盖到 然后在剩下的能覆盖到start的区间里面选择能覆盖到最右端的区间并更新end,然后记录在path里面.如果end的已经将m覆盖则退出循环 如果遍历完所有的区间后end依然没能覆盖到start,则无解 最后按照parh里

UVa 10020 - Minimal coverage(区间覆盖、贪心)

算法入门经典关于区间覆盖的讲解: 8.4.6:区间覆盖问题 数轴上有n个区间[ai,bi],选择尽量少的区间覆盖一条指定线段[s,t]. [分析] 突破口是区间的包含和排序扫描,不过要先进行一次预处理.每个区间在[s,t]外的部分应该首先被切除掉,因为他们的存在是没有意义的.在预处理后,在相互包含的情况下,小区间显然不应该考虑. 把区间按照a从小到大排序.如果区间1的七点不是s,无解,否则选择起点在s的最长区间.选择此区间[ai,bi]后,新的起点应该设置为bi,并且忽略所有区间在bi之前的部分

uva 10020 Minimal coverage(贪心,区间覆盖)

这道题一读就是经典的区间问题,是区间覆盖,敲过之后还有花了很长的调试时间,还是我不熟练,现在做题确实挺慢 的,简单题目也要做好久,没事,慢慢来.最重要的要确保正确率和心态问题,认真对待,调试找到了好多bug,一些 细节问题...都是刚开始没有注意到的.交了之后RE,在数组上多加了两个0.A了,,uva老是不提示数据有多大, 所以只能乱开... 思路: 先对区间按左边的点进行排序,如果当前需要涵盖的区间为[x,y],那么在排序的区间中到左边小于x,右 边最大的那个区间,设为Max,然后更新想找的区

uva 10020- Minimal coverage (贪心思想 简单区间覆盖)

题目大意:给出一个范围M,然后给出若干的区间,以0 0 终止, 要求用最少的区间将0 ~M 覆盖,输出最少个数以及方案. 解题思路:典型的区间覆盖问题,算法竞赛入门经典P154上有讲. /*author: charkj_z */ /*time: 0.108s */ /*rank: 674 */ /*为什么不把没用的地方去掉? 因为去掉了我觉得不像我能写出来的*/ /*Ac code : */ #include<stdio.h> #include<string.h> #include

Timus 1303 Minimal Coverage DP或贪心

1303. Minimal Coverage Given set of line segments [Li, Ri] with integer coordinates of their end points. Your task is to find the minimal subset of the given set which covers segment [0, M] completely (M is a positive integer). Input First line of th