[UVA - 10382] Watering Grass 题解

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[UVA - 10382] Watering Grass 题解相关的知识,希望对你有一定的参考价值。

此文为博主原创题解,转载时请通知博主,并把原文链接放在正文醒目位置。

题目链接(vjudge):https://vjudge.net/problem/UVA-10382

题目大意:

输入包含多组数据。以EOF结束。每组数据给定一个草坪的长L和宽W,草坪的中线上有n个洒水器,给出洒水器的横坐标和洒水半径R。

要求选择最少的洒水器覆盖整片草坪。如果不能覆盖,输出-1.

n<=10000,L,W,R在int范围内。

样例输入:

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

样例输出:

6

2

-1

 

分析:

区间覆盖的贪心问题。虽然洒水范围是个圆,但是容易发现真正有效的是圆与草坪相交得到的矩形。

问题转化为寻找最少的洒水器,使得他们的矩形覆盖整片草地。

注意:

1.W*W会爆int,注意数据类型转换。这个害我改了好久QAQ

2.如果洒水器半径<草坪宽度的一半,可以直接忽略。

 

AC代码:

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<algorithm>
 5 #include<cmath>
 6 #include<queue>
 7  
 8 const int MAXN = 10005;
 9  
10 inline void read(int &x)
11 {
12     char ch = getchar(),c = ch;x = 0;
13     while(ch < 0 || ch > 9) c = ch,ch = getchar();
14     while(ch <= 9 && ch >= 0) x = (x<<1)+(x<<3)+ch-0,ch = getchar();
15     if(c == -) x = -x;
16 }
17 
18 int n,L,w,ans,flag;
19 double tmp,h,last,now;
20 
21 inline int Min(int a,int b)
22 {return a<b?a:b;}
23 
24 inline int Max(int a,int b)
25 {return a>b?a:b;}
26 
27 struct LINE
28 {
29     int mid,area;
30     double l,r;
31 }a[MAXN];
32 
33 int cmp(LINE a,LINE b)
34 {
35     if(a.l == b.l)
36         return a.r > b.r;
37     return a.l < b.l;
38 }
39 
40 int main()
41 {
42     while(scanf("%d%d%d",&n,&L,&w) != EOF)
43     {
44         h = double(w/2.0);ans = 0;
45         flag = false;last = 0,now = 0;
46         for(int i = 1;i <= n;++ i)
47         {
48             read(a[i].mid),read(a[i].area);
49             if(a[i].area <= h){
50                 -- i,-- n;
51                 continue;
52             }
53             tmp = sqrt((double)a[i].area*a[i].area-(double)w*w/4.0);
54             a[i].l = a[i].mid-tmp;
55             a[i].r = a[i].mid+tmp;
56         }
57         std::sort(a+1,a+1+n,cmp);
58         if(a[1].l > 0){
59             printf("-1\n");
60             continue;
61         }
62         for(int i = 1;i <= n+1;++ i)
63         {
64             if(!now && a[i].l > last){
65                 flag = true;
66                 ans = -1;
67                 break;
68             }
69             else if(a[i].l > last || i == n+1){
70                 ans ++;
71                 last = now;
72                 now = 0;
73             }
74             if(last >= L) break;
75             if(a[i].l <= last && a[i].r > now)
76                 now = a[i].r;
77         }
78         if(flag || last < L) printf("-1\n",ans);
79         else printf("%d\n",ans);    
80     }
81     
82     return 0;
83 }

 

以上是关于[UVA - 10382] Watering Grass 题解的主要内容,如果未能解决你的问题,请参考以下文章

UVA - 10382 Watering Grass(几何)

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

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

2017ecjtu-summer training #5 UVA10382

2017暑假 贪心

贪心专题(不定期更新)