您的位置:首页 > 其它

高效算法——E - 贪心-- 区间覆盖

2015-08-05 21:18 260 查看
E - 贪心-- 区间覆盖

题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=85904#problem/E

解题思路:

贪心思想,将问题转化为区间覆盖问题,将草地的上边界作为要覆盖的区间,计算出每个洒水器覆盖的区间范围,不能覆盖的舍去,然后将洒水器按覆盖范围的左边界升序排列。

要覆盖的最右边的点right的初始值为0,遍历洒水器,找一个能覆盖住right且覆盖范围的右边界最大的洒水器,然后将该洒水器覆盖的右边界作为新的right,重复刚才的过程,直到覆盖整个草地。

程序代码:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
#define MAX 10005

struct node
{
double left, right;
bool operator <(const node &a) const
{
return left < a.left;
}
}p[MAX];

int n, num;
double l, w;

int main()
{
int i;
// freopen("input.txt", "r", stdin);
while(scanf("%d %lf %lf", &n, &l, &w) != EOF)
{
num = 0;
double po, r;
for(i = 0; i < n; ++i)
{
scanf("%lf %lf", &po, &r);
if(r <= w/2) continue;
double t = sqrt(r*r-w*w/4.0);
p[num].left = po-t;
p[num++].right = po+t;
}

sort(p, p+num);
double left = 0, right = 0;
bool flag = false;
int result = 0;
i = 0;
if(p[0].left <= left)
{
while(i < num)
{
int j = i;
while(j < num && left >= p[j].left)
{
if(p[j].right > right)
right = p[j].right;
++j;
}
if(j == i) break;
result++;
left = right;
i = j;
if(left >= l)
{
flag = true;
break;
}
}
}

printf("%d\n", flag ? result : -1);
}
return 0;
}


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