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;
}
问 至少装多少个雷达 才能覆盖所有的岛屿
显然任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;
}
相关文章推荐
- Android 二维码生成器
- javascript中的后退和刷新
- 深入理解java语言的class文件格式(五)
- ListView中getChildAt(index)的使用注意事项
- shell安装LAMP环境
- 通信知识片段
- equals和==的区别
- iOS post请求 (普通请求)
- 【有感】——工业4.0来了,我们还能做点什么?
- Android如何获取asset下的xml文件,并解析
- RecyclerView实例-实现可下拉刷新上拉加载更多并可切换线性流和瀑布流模式(1)...
- Oracle到SAP HANA实时复制系列:Replication Agent的安装与配置
- 虚拟机中的Linux系统如何和windows共享文件夹
- mysql自动备份脚本
- 关于使用UICollectionView做选项卡,内部控件越界问题
- android 添加按键(一)
- 深入理解java语言的class文件格式(四)
- MFC实现多个界面跳转
- CentOS的MySQL报错:Can't connect to MySQL server
- JAVA_OPTS