您的位置:首页 > 其它

UVA 10382喷水设施

2014-01-18 17:07 330 查看
UVA 10382

【题目描述】:喷水设置

有一块草坪,长为l,宽为w,在草坪的中心线上,放置规格不一的喷水装置,给定每个装置的安置中心,辐射半径(pos,rad)。求最少几个喷水装置可以辐射整块草坪?

【算法分析】:

把二维退化到一维问题,我们要考虑的辐射边界,pos+(-)sqrt(rad^2-w^2/4),想象一下,如果边界辐射到了,中间一定辐射到了,若rad<w/2的话,是不起作用的,要丢弃。

现在的模型,给定多条线段的,坐标表示(l,r),现在要让这个线段覆盖[0,l]这段范围。用贪心策略,设置当前覆盖的位置np,每次选择一条左端点在np的左边(或包括),右端面最靠右的,贪心模拟即可。为了减少每次选择的复杂度,预先排序即可。

【注意】:但是最坑的是eps啊,一定要注意做差和大小写符号。不然一直W。= =

//深坑,这道题的坑不在于算法,而是eps的处理啊,超时和W的血泪史,eps写不好不仅会W

//更坑的是超时啊

【完整代码】:

#include<iostream>

#include<stdio.h>

#include<string.h>

#include<algorithm>

#include<stdlib.h>

#include<math.h>

#include<queue>

#include<vector>

#include<map>

#define MAXN 10000+5

#define MAXM 50+5

#define oo 95565354451

#define eps 0.000001

#define PI acos(-1.0)//这个精确度高一些

#define REP1(i,n) for(int i=0;i<(n);i++)

#define REP2(i,n) for(int i=1;i<=(n);i++)

using namespace std;

int n;

double l,w;

int cnt;

struct Line

{

double x;

double y;

bool operator <(const Line& l) const

{

return x<l.x;

}

} line[MAXN];

void RandB()

{

cnt=0;

for(int i=0; i<n; i++)

{

double pos,rad;

scanf("%lf%lf",&pos,&rad);

if (rad<w/2) continue;

double sq=sqrt(rad*rad-(w*w)/4);

double x=pos-sq,y=pos+sq;

if (x>=l || y<=0) continue;

line[cnt].x=pos-sq;

line[cnt++].y=pos+sq;

}

sort(line,line+cnt);

}

int solve()

{

double Npos=0;//当前坐标

int p=0;//指针,指向line

int ans=0;

if (line[0].x>eps || cnt==0) return -1;

else

{

while(l-Npos>eps && p<cnt)

{

if (line[p].x-Npos>=eps) break;

double most=Npos;//找到最远的y

while(line[p].x-Npos<=eps && p<cnt)

{

most=max(most,line[p].y);    //x在Npos的左边,贪心去y最大的

p++;

}

ans++;

Npos=most;

}

}

if (l-Npos>=eps) return -1;

else  return ans;

}

int main()

{

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

{

RandB();

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

}

return 0;

}


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