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

这道题一读就是经典的区间问题,是区间覆盖,敲过之后还有花了很长的调试时间,还是我不熟练,现在做题确实挺慢

的,简单题目也要做好久,没事,慢慢来。最重要的要确保正确率和心态问题,认真对待,调试找到了好多bug,一些

细节问题。。。都是刚开始没有注意到的。交了之后RE,在数组上多加了两个0。A了,,uva老是不提示数据有多大,

所以只能乱开。。。

思路:

先对区间按左边的点进行排序,如果当前需要涵盖的区间为[x,y],那么在排序的区间中到左边小于x,右

边最大的那个区间,设为Max,然后更新想找的区间为[Max,m],依次类推,知道没有小于x的区间或者最大值已经大

于了m。。

贴代码:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
using namespace std;
struct node
{
	int x,y;
}a[500005],b[500005];
int cmp(const void *a,const void *b)
{
	if(((node *)a)->x == ((node *)b)->x)
		return ((node *)b)->y - ((node *)b)->y;
	return ((node *)a)->x - ((node *)b)->x;
}
int main()
{
	int T,i,m,x,y;
	cin >> T;
	while(T--)
	{
		cin >> m;
		i = 1;
		while(cin >> x >> y,x||y)
		{
			a[i].x = x;
			a[i].y = y;
			i++;
		}
		int s = i-1;
		qsort(a+1,s,sizeof(a[0]),cmp);
	//	for(i=1; i<=s; i++)
	//		cout << a[i].x << " " << a[i].y << endl;
		int cnt = 0;
		int flag = 0;
		int k=1;
		int flag1 = 0;
		int Max = 0;
		int Max1;
		for(i=1; i<=s; i++)
		{
			if(a[i].x <= cnt)
			{

				if(Max <= a[i].y)
					{
						Max = a[i].y;
						Max1 = a[i].x;
					}
				flag = 1;
				if(i!=s)
					continue;
			}	 

			if(i != s)
				i--;
		//	cout << " i= " << i << endl;
			if(flag == 0)
			{
				break;
			}
			b[k].x = Max1;
			b[k].y = Max;
			//cout << a[i].x << a[i].y << endl;
			k++;
			cnt = Max;
			flag = 0;
			if(cnt >= m)
			{
				flag1 = 1;
				break;
			}

		}
		if(flag1)
		{
			cout << k-1 << endl;
			for(i=1; i<k; i++)
			{
				cout << b[i].x << " " << b[i].y <<endl;
			}
		}
		else
		{
			cout << '0' << endl;
		}
		if(T)
			cout << endl;
	}
	return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-17 02:03:04

uva 10020 Minimal coverage(贪心,区间覆盖)的相关文章

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(区间覆盖并贪心)

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].InputThe first line is the number of test cases, followed by a blank line.Eac

uva10020 - Minimal coverage(区间覆盖)

题目:uva10020 - Minimal coverage(区间覆盖) 题目大意:给出一些线段,然后问怎样取能使得最少的线段覆盖区间[0, M]. 解题思路:先预处理掉那些和区间[0,M]不沾边的线段. 将线段按照起点小的排序. 接着遍历这些线段.首先先判断起点最小的点是否<=0,如果不满足这个说明它不能覆盖区间. 然后每次都小于等于当前覆盖的起点的最长线段,之后要将起点更新成这个最长线段的终点.然后接着判断下一条线段.如果更新了起点发现依然找不到满足条件的线段,说明不能覆盖. 最后还要看一下

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

题意是:输入几个样例,每个样例第一行输入从0开始需要覆盖的长度M,即[0,M].之后输入覆盖的线段,求需要的线段条数最小值. 思路:贪心算法,具体见代码及注释. #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <algorithm> using namespace std; #define MAXN 100001 /*将输入数

UVA 10020 - 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 cases, followed

10382 - Watering Grass(贪心 区间覆盖问题)洒水面覆盖

double qiuzhi(int id) { double t1=cc[id].rid*cc[id].rid; double t2=w*w/4; double t3=t1-t2; double t4=sqrt(t3); return t4; } void to_qujian() { for(int i=0; i<t; i++) { double zhi=qiuzhi(i); qq[i].a=cc[i].pos-zhi; qq[i].b=cc[i].pos+zhi; } } 典型的贪心区间覆盖问

poj 2376 贪心 区间覆盖问题

题意: 给n个区间 选择尽量少的区间 覆盖1~T这个区间 如果不能覆盖 输出-1 思路: 经典贪心 区间覆盖 将所有区间按照起点从小到大排序 取终点在最右边的那个区间 code: #include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #include<vector> #include<string> #include<queue>