第一章-问题求解策略-Uva10382-Watering Grass

分类:贪心
题目链接:Uva10382-Watering Grass
经典的区间贪心

(1) 选择不相交区间 【问题描述】数轴上有n个开区间(ai, bi)。选择尽量多的区间,使这些区间两两没有公共点。

【贪心策略】按bi从小到大的顺序排序,然后一定选择第一个区间。接下来把所有与第一个区间相交的区间排除在外。这样在排序后再扫描一遍即可。

(2) 区间选点问题 【问题描述】数轴上有n个闭区间[ai,
bi]。取尽量少的点,使得每个区间内都至少有一个点(不同区间内含有的点可以是同一个)。

【贪心策略】把所有区间按bi从小到大排序(bi相同时,a从大到小排序),然后一定取第一个区间的最后一个点。

(3) 区间覆盖问题 【问题描述】数轴上有n个闭区间[ai, bi]。选择尽量少的区间来覆盖指定线段[s, t]。

【贪心策略】
1.预处理:扔掉不能覆盖[s, t]的区间。
2.把各区间按a从小到大排序。如果区间1的起点不是s,无解,否则选择起点在s的最长区间。
3.选择此区间[ai, bi]后,问题转化了覆盖[bi, t],于是返回①,直到[s, t]被完全覆盖为止。
选自《NOIP复习资料》

#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
struct M{
    double start;
    double end;
}q[10005];
 
bool cmp (M a,M b) //按最大能覆盖到排序
{
    return a.end>b.end;
}
int main()
{
 	double l,w,p,r;
 	double start,end;
 	int n,i,qn,outn;
    while(cin>>n>>l>>w){
		outn=0;
		start=0.0;end=l;qn=0;
		for(i=0;i<n;i++)
		{
			cin>>p>>r;
			if(2*r>w)
			{
				q[qn].start=p-sqrt(r*r-w*w/4);
				q[qn].end=p+sqrt(r*r-w*w/4);
				qn++;
			}
			
		}
		sort(q,q+qn,cmp);
		while(start<end)
		 {
	 	   	for(i=0;i<qn;i++) 
			{
				if(q[i].start<=start && q[i].end>start )
				{
			    	start=q[i].end;			//更新区间
			    	outn++;
		    		break;
				}
   		 	}
		    if(i==qn) break;		//如果没有一个满足条件的区间,直接结束。
		}
		
		if(start<end) cout<<"-1"<<endl;
		else cout<<outn<<endl;
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值