UVA10382- Watering Grass(区间覆盖问题)

题意:一块长l,宽w的长方形草坪,在其中心线的不同位置处装有n个点状的喷水装置。每个喷水装置i可将以它为中心,半径为ri的圆形区域润湿。请选择尽量少的喷水装置,把整个草坪全部润湿。

思路:变形的区间覆盖问题。其实我们只要将圆形转化为覆盖在草坪上的矩形即可。当半径ri<w/2时,圆形面积在草坪真正有用的只是一条竖线,对于完全覆盖草坪没有任何意义,所以这种喷水装置不取。转化完之后,只要按照区间覆盖问题去解决就行了。先判断是否能从开头开始覆盖,之后每次取起点相同,但是区间长度最长的那个区间(期间注意判断是否能覆盖每一个地方)。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>

using namespace std;

const int MAXN = 10005;

struct node{
    double s, e;
}t[MAXN];

int n;
double l, w;

int cmp(node a, node b) {
    if (a.s != b.s)
        return a.s < b.s;
    else
        return a.e > b.e;
}

int main() {
    while (scanf("%d%lf%lf", &n, &l, &w) != EOF) {
        int cnt = 0;
        for (int i = 0; i < n; i++) {
            double  p, r;
            scanf("%lf%lf", &p, &r);
            if (r > w / 2) {
                double temp = sqrt(r * r - w * w / 4);
                t[cnt].s = p - temp;
                t[cnt].e = p + temp;
                cnt++;
            }
        }

        sort(t, t + cnt, cmp);
        int num = 0, flag = 0;
        double start = 0, end = 0;
        if (t[0].s <= 0) {
            int left = 0;
            while (left < cnt) {
                int right = left;
                while (right < cnt && t[right].s <= start) {
                    if (t[right].e >= end)
                        end = t[right].e;
                    right++;
                }
                if (right == left) {
                    break;
                }
                num++;
                left = right;
                start = end;
                if (start >= l) {
                    flag = 1;
                    break;
                }
            }
        }

        if (flag)
            printf("%d\n", num);
        else
            printf("-1\n");
    }
    return 0;
}

UVA10382- Watering Grass(区间覆盖问题)

时间: 2024-10-02 00:44:49

UVA10382- Watering Grass(区间覆盖问题)的相关文章

uva10382 - Watering Grass(区间覆盖变形)

题目:uva10382 - Watering Grass(区间覆盖变形) 题目大意:要给一片草坪浇水,给定草坪的长度和宽度,给出每个喷头的圆心C和喷水的半径R,问最少要几个喷头可以给整片草坪都浇上水. 解题思路:区间覆盖问题的变形,因为草坪有宽度W,所以这个每个喷头的有效范围是[C- sqrt(R* R - 0.25 * W * W   ,  C + sqrt (R*R - 0.25 * W *W)]. 代码: #include <stdio.h> #include <algorithm

区间选点+区间覆盖

区间选点+区间覆盖 区间选点问题(选择最少的点,使得每个区间都至少有k个点) 将这些区间[l,r]先按照r从小到大排序,再按照l从大到小排序.选点尽量选择靠近右边界的点.然后按照这个排序后的区间进行遍历,用一个变量来存放遍历过程中上个区间的右边界,然后碰到一个新的区间的时候需要分两种情况讨论:1.这个区间和上个区间有相交的部分,那么就需要判断一下上次选择的点有多少在这个区间内,这些点满足要求吗?不满足的话还需要在这个区间内选点2.这个区间和上个区间没有交集,那么这个区间就需要选点. 上述策略可以

10382 - Watering Grass(贪心 区间覆盖问题)洒水面覆盖

double qiuzhi(int id) { double t1=cc[id].rid*cc[id].rid; double t2=w*w/4; double t3=t1-t2; double t4=sqrt(t3); return t4; } void to_qujian() { for(int i=0; i<t; i++) { double zhi=qiuzhi(i); qq[i].a=cc[i].pos-zhi; qq[i].b=cc[i].pos+zhi; } } 典型的贪心区间覆盖问

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

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

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

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

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(贪心)

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 解题心得

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

ural Minimal Coverage (区间覆盖)

http://acm.timus.ru/problem.aspx?space=1&num=1303 给出一些区间,选择尽量少的区间能覆盖到[0,m]. 小白p154,典型的区间覆盖问题.一直在想怎么dp.. 首先预处理,先按左端点从小到大排序,若左端点相同右端点从大到小排序,若区间x完全包含y,按照贪心的思想,y是没有意义的,有大区间可以选何必选择小区间.处理完事之后各个区间满足a1 <= a2 <= a3....且b1 <= b2 <= b3... 这样找到第一个覆盖0的