您的位置:首页 > 其它

UVA10382喷水装置

2014-11-02 11:35 211 查看
题意:

给你一个矩形的空地,然后有一些圆形的喷水装置,每个装置的圆心都在矩形宽的中间位置,然偶给你每个矩形的圆心位置和半径,问你最少多少个喷水装置可以把矩形的所有编辑都覆盖上。

思路:

首先我们要把所有的圆都处理成矩形,也就是每个圆的最大覆盖矩形范围(除了矩形的部分,其他部分没意义,因为只有矩形能接壤上,不然会有空隙),然后变成了最小区间覆盖问题,最小区间覆盖问题可以用贪心的方式处理,刚做完UVA10020就是有一个单纯的求最小区间覆盖,那个题解刚写完,我直接把那个题解粘贴过来吧:

大体思路可以是这样,我们先把所有的区间按照起点从小到大排序,然后我们定义一个当前覆盖位置pos,初始是0,也就是[0,m]的最左端,然后我们从小区间中找到一个可以覆盖pos点并且右端点最远的一个(记得sum++),然后把最远的这个右端点作为当前的pos,继续找下一个,至于实现,我是自己写的,可能写的不是很简洁,不知道网上有没有简洁点的,如果没有就讲究看下我的吧,具体细节看代码。

#include<math.h>

#include<stdio.h>

#include<algorithm>

#define N 11000



using namespace std;



typedef struct

{

double l ,r;

}EDGE;

EDGE edge
;

bool camp(EDGE a ,EDGE b)

{

return a.l < b.l;

}

int main ()

{

int n ,l ,w ,i;

double x ,r;

while(~scanf("%d %d %d" ,&n ,&l ,&w))

{

double w2 = w * 1.0 / 2;

int nowid = 0;

for(i = 1 ;i <= n ;i ++)

{

scanf("%lf %lf" ,&x ,&r);

if(r <= w2) continue;

double tmp = sqrt(r * r - w2 * w2);

double ll = x - tmp ,rr = x + tmp;

if(rr < 0 || ll > l) continue;

nowid ++;

edge[nowid].l = ll ,edge[nowid].r = rr;

}

sort(edge + 1 ,edge + nowid + 1 ,camp);

int Ans = 0;

double pos = 0 ,max = 0;

for(i = 1 ;i <= nowid ;i ++)

{

if(pos > edge[i].r) continue;

if(edge[i].l <= pos)

{

if(max < edge[i].r) max = edge[i].r;

if(i == nowid)

{

if(max < l){Ans = -1 ;break;}

Ans ++;

}

}

else

{

if(max == 0){Ans = -1 ;break;}

pos = max;

if(pos >= l) break;

max = 0 ,Ans ++ ,i --;

}

}

if(!Ans) Ans = -1;

printf("%d\n" ,Ans);

}

return 0;

}





内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: