[UVA10382]Watering

Posted by John on 2016-01-21
Words 755 and Reading Time 3 Minutes
Viewed Times

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

題意: 用最小數目的圓形把長方形面積都覆蓋住,貪心問題。

想法: 一開始想以圓形的最左和最右當端點,但是後來發現會有無法完全覆蓋(有隙縫)的情形,參考網路上的想法後改成轉換成長方形左右兩端當成端點,並且要注意圓形的半徑如果無法將長方形的寬覆蓋住則不列入考慮。

這題看似簡單……做起來折騰了好久阿。

CPE上的測資真的弱到爆,CPE過了拿去UVA居然沒過,為此DEBUG好久……後來結論是我在for判斷的時候是以圓圈的數量作為條件,所以如果是最後一個點才完成覆蓋所有面積,這樣的情形我就不會判斷到,所以要移動一下判斷的位置

//使用Java的考生請注意,最外層的類別(class)需命名為 main 。 
//如果遇到超乎想像的狀況,請更改編譯器試看看!! 各編譯器特性不同!!
//預設測資、隨機測資、固定測資是用來幫助除錯用的。批改時,只看暗中測資是否通過!!
#include <stdio.h>
#include <stdlib.h>
#include <utility>
#include <vector>
#include <math.h>
#include <algorithm>
using namespace std;
bool cmp(pair<double,double> p1,pair<double,double> p2) {
return p1.second > p2.second;
}
pair<double,double> change(pair<double,double> p,int w) {
double r = sqrt(p.second*p.second - (double)w*w/4);
p.second = p.first + r;
p.first = p.first - r;
return p;
}
int main() {
int n,l,w;
while(scanf("%d %d %d",&n,&l,&w) == 3) {
double pos,rad;
vector<pair<double,double> >s;
while(n--) {
scanf("%lf %lf",&pos,&rad);
if(2*rad > w)
s.push_back( change(make_pair(pos,rad),w) );
}
sort(s.begin(),s.end(),cmp);
double start = 0;
int count = 0;
bool flag = false;
for(int i = 0 ; i < s.size() ; ++i) {
double temp = 0;
vector<pair<double,double> >::iterator it;
for(it = s.begin() ; it != s.end() ; it++) {
if( it->first <= start && it->second > temp) {
//printf("* %lf %lf\n",it->first,it->second);
temp = it->second;
//printf("new start : %lf\n",temp);
}
}
start = temp;
count++;
if(start >= l) {
printf("%d\n",count);
flag = true;
break;
}
}
if(!flag) printf("-1\n");
}
return 0;
}

>