您的位置:首页 > 其它

POJ-Radar Installation-贪心-区间选点

2015-11-19 11:43 232 查看
给n个岛屿的坐标,给一个d,表示 安装在X轴上的雷达的有小半径

问 至少装多少个雷达 才能覆盖所有的岛屿

显然任1 个岛屿的y大于d 就是无解的方案,输出-1

其余情况 其实 和  【区间选点】问题是一样的

每个岛屿 对应一个区间【a,b】 表示 这个区间内 安装雷达,都会使得该岛屿能被覆盖

n个区间,怎么选点 使得 点最少,而 每个区间至少存在一个点 ,这就是【区间选点】问题

对区间的b(右端点)升序排序,b相同按a升序排序

从第一个开始选,要在第一个区间填上一个点 并且使得 尽量覆盖更多的区间,显然是 把点填在 【区间的右端点】最优,不存在其他更好的方案,

因此 当 接下来的区间的左端点小于等于 这个右端点的时候,就已经被覆盖了,

【直到遇到一个区间的左端点 大于 之前填过的点】,这时候说明需要再填一个点。。。重复这个步骤直到 全部区间考虑完

就是答案了

#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <iostream>
#include <queue>
#include <map>
#include <set>
#include <vector>
using namespace std;

struct node
{
double x,y;
};
node tm[1005];
int cmp(node a,node b)
{

if (a.y!=b.y)
return a.y<b.y;
else
return a.x<b.x;
}
double inf = 2147483647;
int main()
{
int i;
int n,d;
int cnt=1;
while(cin>>n>>d)
{
if (!n&&!d) break;

int x,y;
int flag=0;
for(i=1;i<=n;i++)
{
scanf("%d%d",&x,&y);
if (abs(y)>d)
flag=1;
double dis ;
dis=sqrt((double)(d*d-y*y));
tm[i].x=x-dis;
tm[i].y=x+dis;
}
if (flag)
{
printf("Case %d: %d\n",cnt++,-1);
continue;
}
sort(tm+1,tm+1+n,cmp);
int ans=0;
double start=-inf;
for(i=1;i<=n;i++)
{
if (tm[i].x>start)
{
start=tm[i].y;
ans++;
}
else
continue;
}
printf("Case %d: %d\n",cnt++,ans);
}

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