POJ-2376

区间覆盖
描述
数轴上有 n (1<=n<=25000)个闭区间 [ai, bi],选择尽量少的区间覆盖一条指定线段 [1, t]( 1<=t<=1,000,000)。
覆盖整点,即(1,2)+(3,4)可以覆盖(1,4)。
不可能办到输出-1

输入
第一行:N和T
第二行至N+1行: 每一行一个闭区间。

输出
选择的区间的数目,不可能办到输出-1

样例输入
3 10
1 7
3 6
6 10

样例输出
2

解题思路
先判断起点有没有被覆盖,然后就是选区间覆盖范围最大的那个,选了区间A后,要把所有包含了A右端点的区间给剪断,即把他们的左端点都给变成A的右端点,然后循环。

代码实现

#include<stdio.h>
#include<algorithm>
#include<iostream>
using namespace std;
struct P{
	int left,right; //左右 
	
	bool operator<(const P &p){  //按左端点升序,右端点降序
		if(left!=p.left )  return left<p.left;
		if(right!=p.right)  return right>p.right;
		else return 1;
	}
};

P p[1000];
int N,T;
int al;//选取区间个数
int ii;//用来剪枝的
int a;

int F(int aa)   //找到p[ii] 后面第一个left大于aa的区间
{
	for(int i = ii ;i<N;i++)
	{
		if(p[i].left > aa)
		return i;
	}
	return N-1;
}

/*
void sortp(int x,int y)
{
	for(int i=x;i<y+1;i++)
	{
	for(int j=i;j<y;j++)
		{
			if(p[j].left > p[j+1].left)
			{
				P a = p[j];
				p[j] = p[j+1];
				p[j+1]  = a;
			}
			else if(p[j].left == p[j+1].left &&p[j].right<p[j+1].right)
			{
				P a = p[j];
				p[j] = p[j+1];
				p[j+1]  = a;
		//		cout<<"1"<<endl;
			}
		}
	}
}
*/

int find( int f )  //输入起点,返回下一个起点
{
	for(int i=0;i<N;i++)
	{
		if( f == p[i].left)
		{
			al++;
			ii =i;  //找到这个区间的索引 
	//		cout<<"选第"<<i<<endl;
			return p[i].right+1;
		}
	}
	return -1;
}

void cut( int l)   //剪断操作
{
	for(int i=ii;i<N;i++)
	{
		if(p[i].right > l && p[i].left < l)
		{
			p[i].left = l;
		}
	}
//	for(int i=0;i<N;i++)
//		cout<<p[i].left<<" "<<p[i].right<<" "<<endl;
	int c = F(a);
	//cout<<a<<"*"<<c<<endl;
//	cout<< "sort("<<ii<<","<<c<<")"<<endl;
	sort(p+ii,p+c+1);
//	for(int i=0;i<N;i++)
//		cout<<p[i].left<<" "<<p[i].right<<" "<<endl;
}


int main()
{
	while( scanf("%d %d",&N,&T) !=EOF){
	al=0;ii=0;
	for(int i=0;i<N;i++)
	{
		scanf("%d %d",&p[i].left,&p[i].right);
	}
	sort(p,p+N);
//	for(int i=0;i<N;i++)
//		cout<<p[i].left<<" "<<p[i].right<<endl;
	if(p[0].left > 1)  {printf("-1\n");return 0;}
	a = find(1);
	cut(a);
	//cout<< a<<" * "<<ii<<endl;
	while(a != -1 )
	{
		if(a>T)  break;
		a = find(a);
	//	cout<<a<<endl;
		cut(a);
	//	cout<< a<<" ** "<<ii<<endl;
	}
	if( a == -1) {printf("-1\n");return 0;}
	else printf("%d\n", al);
	}
	return 0;
 } 

小结
因为如果硬要全部排序的话会造成超时,所以我就想了办法给他优化了,刚开始结果一直错,调试的时候发现是排序出问题了,我还以为sort函数不能这样用,自己写了个sortp函数,居然也是错的,后来经历一番波折,发现是我sort 的参数写错了,导致排序的不彻底。

发布了32 篇原创文章 · 获赞 1 · 访问量 1059

猜你喜欢

转载自blog.csdn.net/Hanpi_learnc/article/details/104838566