Watering Grass——UVA10382

题目

 n sprinklers are installed in a horizontal strip of grass l meters long and w meters wide. Each sprinkler is installed at the horizontal center line of the strip. For each sprinkler we are given its position as the distance from the left end of the center line and its radius of operation. What is the minimum number of sprinklers to turn on in order to water the entire strip of grass? Input Input consists of a number of cases. The first line for each case contains integer numbers n, l and w with n ≤ 10000. The next n lines contain two integers giving the position of a sprinkler and its radius of operation. (The picture above illustrates the first case from the sample input.) Output For each test case output the minimum number of sprinklers needed to water the entire strip of grass. If it is impossible to water the entire strip output ‘-1’. Sample Input 8 20 2 5 3 4 1 1 2 7 2 10 2 13 3 16 2 19 4 3 10 1 3 5 9 3 6 1 3 10 1 5 3 1 1 9 1 Sample Output 6 2 -1

题目大意

最小区间覆盖

eof结束

 给定n l w分别是 数量 长度 宽度

n次输入 每次输入喷壶的位置和半径

然后求最少个能覆盖的喷壶数

算法: 贪心 最小区间覆盖 

代码 

/*给定一个端点n,再给一定数量的区间[li,ri] ,问覆盖[0,n]( m初始为0 )最少需要多少个区间,如果不能输出0。。
为了能使一个区间覆盖的更多,将所有区间按右端点降序排序,如果一个区间[l,r] 覆盖了start ,
则说明[0,r]已经被覆盖,所以令start=r,剩下需要被覆盖的为[r,n] (在r<n的情况下,若r>=n,则说明[m,n]被完全覆盖,直接结束)
*/
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
struct M{
    double start;
    double end;
}q[10005];
 
double 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;
}

 相关看 https://blog.csdn.net/baidu_41907100/article/details/84673955

注意

一开始我的一直WA 然后百度对比之后发现不同点在于

 

也就是判断圆直径是否大于宽度的顺序不同 我实在是不知道为什么顺序不同如何导致的错误

附上错误代码

/*给定一个端点n,再给一定数量的区间[li,ri] ,问覆盖[0,w]( m初始为0 )最少需要多少个区间,如果不能输出0。。
为了能使一个区间覆盖的更多,将所有区间按右端点降序排序,如果一个区间[l,r] 覆盖了start ,
则说明[0,r]已经被覆盖,所以令start=r,剩下需要被覆盖的为[r,n] (在r<n的情况下,若r>=n,则说明[m,n]被完全覆盖,直接结束)
*/
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
struct M{
	double p;
	double r; 
    double start;
    double end;
}q[10005];
 
double cmp (M a,M b) //按最大能覆盖到排序
{
    //return a.r>b.r;
    return a.end>b.end;
}
int main()
{
 	double l,w;
 	double start,end;
 	int n,i,outn;
    while(cin>>n>>l>>w){
		outn=0;
		start=0.0;end=l;
		for(i=0;i<n;i++)
		{
			cin>>q[i].p>>q[i].r;
			q[i].start=q[i].p-sqrt(q[i].r*q[i].r-(w/2)*(w/2));
			q[i].end=q[i].p+sqrt(q[i].r*q[i].r-(w/2)*(w/2));
		}
		sort(q,q+n,cmp);
		while(start<end)
		 {
	 	   	for(i=0;i<n;i++) 
			{
				if(q[i].start<=start && q[i].end>start && 2*q[i].r>w)
				{
			    	start=q[i].end;			//更新区间
			    	outn++;
		    		break;
				}
   		 	}
		    if(i==n) break;		//如果没有一个满足条件的区间,直接结束。
		}
		
		if(start<end) cout<<"-1"<<endl;
		else cout<<outn<<endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/baidu_41907100/article/details/84843994