您的位置:首页 > 其它

POJ 1328 Radar Installation(区间覆盖、贪心)

2017-01-13 20:23 429 查看
题目连接:http://poj.org/problem?id=1328

总时间限制: 500ms    内存限制: 65536kB

Description

Assume the coasting is an infinite straight line. Land is in one side of coasting, sea in the other. Each small island is a point locating in the sea side. And any radar installation, locating on the coasting, can only cover d distance, so an island in the sea can be covered by a radius installation, if the distance between them is at most d.

We use Cartesian coordinate system, defining the coasting is the x-axis. The sea side is above x-axis, and the land side below. Given the position of each island in the sea, and given the distance of the coverage of the radar installation, your task is to write a program to find the minimal number of radar installations to cover all the islands. Note that the position of an island is represented by its x-y coordinates.



Input

The input consists of several test cases. The first line of each case contains two integers n (1<=n<=1000) and d, where n is the number of islands in the sea and d is the distance of coverage of the radar installation. This is followed by n lines each containing two integers representing the coordinate of the position of each island. Then a blank line follows to separate the cases.

The input is terminated by a line containing pair of zeros

Output

For each test case output one line consisting of the test case number followed by the minimal number of radar installations needed. “-1” installation means no solution for that case.

Sample Input

3 2

1 2

-3 1

2 1

1 2

0 2

0 0

Sample Output

Case 1: 2

Case 2: 1

Source

Beijing 2002

题意

x轴上面是岛屿(点),下面是陆地,需要在陆地上建立观测站,观测半径是D,问最少建几个观测站能够观测到所有的岛屿。

解题思路

很明显,要想达到最优解,所有的观测站应该建造在x轴上。另外,对于每个岛屿来说,如果y坐标大于半径D,则无论如何也无法满足条件。对于y坐标小于D的点,我们可以反过来以岛屿为圆心,以D为半径画圆,这样我们可以在x轴上得到一些弦。如此我们就把问题转化为如何在这些弦上选取最少的点覆盖所有的区间。

直接用贪心的思想就可以求解,类似于求解最大独立集,按照区间左端坐标排序,依次遍历。若当前区间段没有被标记,则将该区间标记,取区间右端坐标作为观测站建立点,并把所有与该区间有重复的区间也标记上。如此遍历到最后就是最终的解。

注意:区间坐标要用浮点型数据表示,所以比较大小的时候,也要注意浮点型数据比较大小不能直接判等,以及需要使用eps比较大小。具体见代码。

AC代码

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
using namespace std;
#define eps 1e-8
const int num=1005;

int n,d,vis[num],ans;
struct node{
int x,y;
}island[num];
struct task{
double s,t;
}radar[num];
bool cmp(task x,task y){
return eps<y.t-x.t;
}

int main()
{
int x,y,cas=1,maxy;
double xx,yy;
while(~scanf("%d%d",&n,&d)&&n&&d)
{
memset(vis,0,sizeof(vis));
maxy=0;
ans=0;
for(int i=0;i<n;i++)
{
scanf("%d%d",&x,&y);
island[i].x=x;
island[i].y=y;
if(y>maxy)  maxy=y;
}
printf("Case %d: ",cas++);
if(maxy>d){
printf("-1\n");
continue;
}
for(int i=0;i<n;i++){
xx=island[i].x-sqrt(d*d*1.0-island[i].y*island[i].y);
yy=island[i].x+sqrt(d*d*1.0-island[i].y*island[i].y);
radar[i].s=xx;
radar[i].t=yy;
}
sort(radar,radar+n,cmp);
for(int i=0;i<n;i++){
if(!vis[i]){
vis[i]=1;
//cout<<i<<"%%%"<<endl;
ans++;
for(int j=0;j<n;j++){
if(radar[j].s<radar[i].t+eps&&!vis[j]){
vis[j]=1;
}
}
}
}
printf("%d\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  poj 贪心 区间覆盖