[C ++] "One Book 1.1 Example 3" water spraying device (Watering Grass)

【source】

A general question bank-1424
UVA-10382
LibreOJ-10002
Kattis-grass
vjudge

The questions in each question bank have the same meaning, but the input format and data range are slightly different.

【Title description】

long L L meters, wide W W meter lawn is filled n n irrigation sprinklers. Each nozzle is installed on the center line of the lawn (from each side W 2 \frac{W}{2} Meter). We know the location of each sprinkler (distance from the left end of the lawn's centerline) and the range of watering it can cover.
Insert picture description here

I would like to ask: If you want to irrigate the entire lawn at the same time, how many sprinklers do you need to open at least?

【Input format】

The input contains several sets of test data.

An integer in the first line T T represents the number of data groups;

The first row of each set of data is an integer n L n、L and W W

In the next n rows, each row contains two integers, giving the position of a sprinkler and the irrigation radius (the above schematic is the case described in the sample input of the first set of data).

【Output format】

A number is output for each set of test data, indicating the minimum number of sprinklers required to irrigate the entire lawn. If all sprinklers are turned on and the entire lawn cannot be watered, the output 1 −1

【Input example】

3
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

【data range】

For 100% data, n≤15000.

【Analysis】

greedy.

Find the effective range of water sprayed by the spray head and filter out the spray head whose spray diameter is smaller than the width of the lawn.

Then the problem can be transformed into an interval full coverage problem, which is equivalent to a given length of m m interval, then give n n The start and end points of line segments (note that this is a closed interval). Find the minimum number of line segments to completely cover the entire interval.

Arrange each section in ascending order of the left end point. The greedy strategy here is to select the largest right end point in the selectable line segment each time until it is completely covered.

【Code】

Yitongtong / LibreOJ:

#pragma GCC optimize(3,"Ofast","inline")
#pragma G++ optimize(3,"Ofast","inline")

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

#define RI                 register int
#define re(i,a,b)          for(RI i=a; i<=b; i++)
#define ms(i,a)            memset(a,i,sizeof(a))
#define MAX(a,b)           (((a)>(b)) ? (a):(b))
#define MIN(a,b)           (((a)<(b)) ? (a):(b))

using namespace std;

typedef long long LL;

const int N=15005;

struct Node {
    double l,r;

    bool operator < (const Node &rhs) const {
        return l<rhs.l;
    }
} a[N];

int main() {
    int T;
    scanf("%d",&T);
    while(T--) {
        int n,L,W;
        scanf("%d%d%d",&n,&L,&W);
        int cnt=0;
        for(int i=1; i<=n; i++) {
            int x,r;
            scanf("%d%d",&x,&r);
            if(r<W/2.0) continue;
            double tmp=sqrt(r*r-W*W/4.0);
            a[++cnt].l=1.0*x-tmp;
            a[cnt].r=1.0*x+tmp;
        }
        sort(a+1,a+cnt+1);
        double t=0;
        int ans=0,i=1,flag=0;
        while(t<L) {
            ans++;
            double s=t;
            while(a[i].l<=s && i<=cnt) {
                if(t<a[i].r) t=a[i].r;
                i++;
            }
            if(t==s && s<L) {
                printf("-1\n");
                flag=1;
                break;
            }
        }
        if(!flag) printf("%d\n",ans);
    }
    return 0;
}

UVA / Kattis:
// Note: The variable type entered in UVA should use floating point

#pragma GCC optimize(3,"Ofast","inline")
#pragma G++ optimize(3,"Ofast","inline")

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

#define RI                 register int
#define re(i,a,b)          for(RI i=a; i<=b; i++)
#define ms(i,a)            memset(a,i,sizeof(a))
#define MAX(a,b)           (((a)>(b)) ? (a):(b))
#define MIN(a,b)           (((a)<(b)) ? (a):(b))

using namespace std;

typedef long long LL;

const int N=1e4+5;

struct Node {
    double l,r;

    bool operator < (const Node &rhs) const {
        return l<rhs.l;
    }
} a[N];

int main() {
    int n,L;
    double W;
    while(~scanf("%d%d%lf",&n,&L,&W)) {
        int cnt=0;
        for(int i=1; i<=n; i++) {
            double x,r;
            scanf("%lf%lf",&x,&r);
            if(r<W/2) continue;
            double tmp=sqrt(r*r-W*W/4);
            a[++cnt].l=x-tmp;
            a[cnt].r=x+tmp;
        }
        sort(a+1,a+cnt+1);
        double t=0;
        int ans=0,i=1,flag=0;
        while(t<L) {
            ans++;
            double s=t;
            while(a[i].l<=s && i<=cnt) {
                if(t<a[i].r) t=a[i].r;
                i++;
            }
            if(t==s && s<L) {
                printf("-1\n");
                flag=1;
                break;
            }
        }
        if(!flag) printf("%d\n",ans);
    }
    return 0;
}
Published 106 original articles · praised 156 · 40,000+ views

Guess you like

Origin blog.csdn.net/Ljnoit/article/details/105342029