uva 10382

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 nl 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

题意:

有一个草坪,在草坪中有一些喷水装置,给出这个草坪的长和宽,和喷水装置的位置和半径,求最少放置多少个喷水装置能使得草坪被全部覆盖?

思路

这是一个区间覆盖问题,可以参考算法竞赛与入门经典P233,但是这个问题是圆形区域覆盖,不好计算,因此我们把圆形区域转换到草坪上来,就变成了矩形区域,这样便于计算。

代码:

#include<iostream>
#include<cmath>
using namespace std;
class Circle
{
public:
    double left,right;

}
circle[10005];
int main()
{
    int num;
    double lenth,width;
    while(cin>>num>>lenth>>width)
    {
        int i,j,k=0;
        double pos,radius;
        for(i=0; i<num; i++)
        {
            cin>>pos>>radius;
            if(radius*2>=width)
            {
                double l,r;
                l=pos-sqrt(radius*radius-(width/2)*(width/2));
                r=pos+sqrt(radius*radius-(width/2)*(width/2));
                circle[k].left=l;
                circle[k++].right=r;
            }
        }
        double begin=0,end=lenth;
        double maxlen=0;
        int cnt=0;
        while(begin<end)
        {
            maxlen=0;
            for(i=0; i<k; i++)
            {
                if(circle[i].left<=begin&&circle[i].right>maxlen)
                {
                    maxlen=circle[i].right;
                }
            }
            if(maxlen==begin)
            {
                cnt=-1;
                break;
            }
            cnt++;
            begin=maxlen;
        }
        cout<<cnt<<endl;
    }
    return 0;
}

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

时间: 2024-10-14 10:10:09

uva 10382的相关文章

uva 10382 Watering Grass(贪心)

uva 10382 Watering Grass 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 f

Uva 10382 (区间覆盖) Watering Grass

和 Uva 10020几乎是一样的,不过这里要把圆形区域转化为能够覆盖的长条形区域(一个小小的勾股定理) 学习一下别人的代码,练习使用STL的vector容器 这里有个小技巧,用一个微小量EPS来弥补浮点运算中的误差 1 //#define LOCAL 2 #include <vector> 3 #include <cstdio> 4 #include <cmath> 5 #include <algorithm> 6 #include <functio

UVa 10382 Watering Grass (区间覆盖贪心问题+数学)

题意:有一块长为l,宽为w的草地,在其中心线有n个喷水装置,每个装置可喷出以p为中心以r为半径的圆, 选择尽量少的装置,把草地全部润湿. 析:我个去啊,做的真恶心,看起来很简单,实际上有n多个坑啊,首先这个题,应该可以看出来是贪心算法, 具体的说是区间覆盖问题,这个问题总体来说不难,但是在这有了巨多的坑.要注意以下几点: 1.这是一个草坪,不是线段,首先你要先把实验室转化为线段. 2.这个喷水装置喷出是圆,不是矩形,要运用数学知识进行运算. 3.输入的半径的两倍如果小于等于宽度,就得忽略不记.因

UVa 10382 - Watering Grass 解题心得

原题: 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 t

uva 10382 - Watering Grass(区域覆盖问题)

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 题目大意: 有一块草坪,长为l,宽为w,在它的水平中心线上有n个位置可以安装喷水装置,各个位置上的喷水装置的覆盖范围为以它们自己的半径ri为圆.求出最少需要的喷水装置个数. 分析与总结: 这题的关键在于转化 根据这图可以看出,一个喷水装置的有效覆盖范围就是圆中间的那个矩

UVA - 10382 Watering Grass(几何)

题意:有一个矩形,n个圆.已知矩形的长宽和圆的半径,问最少需多少个圆将矩形完全覆盖. 分析: 1.首先求圆与矩形的长的交点,若无交点,则一定不能对用最少的圆覆盖矩形有贡献. 2.如果两个圆与矩形相交所得的线段重合,那这两个圆一定能把矩形在两线段并集的那部分所覆盖.问题转化为用圆与矩形相交所得的线段覆盖矩形的长. 3.按线段左端点排序,对于某个已选择的线段a,求它后面满足b.L <= a.R的线段b的b.R的最大值,依次类推. #include<cstdio> #include<cs

UVA 10382 Watering Grass

问题可以转化为草坪的边界被完全覆盖.这样一个圆形就换成一条线段. 贪心,从中选尽量少的线段把区间覆盖,按照把线段按左端点排序,记录一个当前已经覆盖区间的位置cur, 从左端点小于等于cur选一个右端点最大的作为这次选的区间,如果没有符合条件的,说明不可能完全覆盖. r*r会爆int... #include<bits/stdc++.h> using namespace std; const int maxn = 1e4+5; int n,l,w; struct seg { double l,r;

UVA 10382 Watering Grass(区间覆盖,贪心)题解

题意:有一块草坪,这块草坪长l 米,宽 w 米,草坪有一些喷头,每个喷头在横坐标为 p 处,每个喷头的纵坐标都是(w/2) ,并且喷头的洒水范围是一个以喷头为圆心,半径为 r 米的圆.每次最少需要打开多少个喷头来给草坪洒水,并且草坪各处都能被洒到,不行输出-1 思路:这是一道区间覆盖(贪心)题: 有一堆区间 l1, r1:l2, r2...ln,rn,问你最少用几个能覆盖0~P的长度 那么我们先按照L升序排序,far是目前所能找到的最远处,R是上一次查询所能找到的最远处,每次查询我们都要找后面满

大白书

UVA 11292 (简单贪心) 题意: n条恶龙,m个勇士,用勇士来杀恶龙.一个勇士只能杀一个恶龙.而且勇士只能杀直径不超过自己能力值的恶龙.每个勇士需要支付能力值一样的金币.问杀掉所有恶龙需要的最少金币. 思路: 贪心,均从小到大排序.为每一条龙找一个恰好能杀他的骑士.简单贪心. UVA 11729 (经典贪心问题) 题意: n个任务,需要交代B分钟,执行J分钟,让你合理选择交代任务的次序,求得n个任务完成的最小总时长. 思路: 经典贪心,通过比较俩俩的关系,得到整个序列的贪心排序方法.这个