ACM草地上洒水需要的最少的喷泉数

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

解题思路:

题目的大一时给定一段草地的长度和宽度还有在这个草地上的喷泉的数目以及这些喷泉的所处的位置,还有这些喷泉的可以喷射的半径,问我们可不可以喷洒到这整块草地,如果不能喷射到整个草地,就输出-1,否则就要输出最少需要多少个喷泉就能喷洒到所有的区域。我们要注意的就是我们的草地是一块矩形区域,我们要把喷洒范围为圆形的喷泉转化为一个矩形来处理。就是用勾股定理来求出每一个圆形的喷洒区间(x-sqrt(r*r-w*w/4) , x+sqrt(r*r-w*w/4))。这样我们就把这个问题转换为了一个区间覆盖的问题。

程序代码:

#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
int n,sum;
double l,w,s,r;
struct node 
{
	double x;
	double y;
}a[10005];
double fun(node a,node b)
{
	return a.y>b.y;
}
int main()
{
	while(cin>>n>>l>>w)
	{
		sum=0;
		double g=0;
		for(int i=0;i<n;i++)
		{
			cin>>s>>r;
			a[i].x=s-sqrt(r*r-w*w/4);
			a[i].y=s+sqrt(r*r-w*w/4);
		}
		sort(a,a+n,fun);
		while(g<l)
		{
			int k;
			for(k=0;k<n;k++)
			{
				if(a[k].x<=g&&a[k].y>g)
				{
					g=a[k].y;
					sum++;
					break;
				}
			}
			if(k==n)
		    	break;
		}
		if(g<l)
			cout<<"-1"<<endl;
		else
			cout<<sum<<endl;
	}
	return 0;
}

  

原文地址:https://www.cnblogs.com/xinxiangqing/p/4715548.html