POJ-1328-Radar Installation
这道题目是数学+贪心哦~
题目大意:有一条无限的海岸线,海岸线的一边是海洋,海岸线的另一边是陆地,其中海洋上面有些许岛屿,现如今要安装雷达系统来检测各个岛屿情况,给出各个岛屿的坐标位置和一个雷达最多能到达的半径d(雷达能检测到的范围是半径为r的圆)问最少需要花费多少个雷达才能够把所有的岛屿都给检测到。
如果不能检测到所有岛屿,那么输出-1即可。
本题思路:
我们先来考虑特殊情况:什么时候输出-1呢?
当我们输入的d小于0或者岛屿的纵坐标的绝对值大于d的时候,我们就得输出-1.
所以我们在输入的时候就记录绝对值最大的纵坐标。然后进行判断。
那么按照贪心策略如何获得最少的雷达呢。
我们主要还是以每个岛屿为圆心,画半径为d的圆,与X轴的交点有一个或者两个,记录到结构体中,对结构体进行排序。(升序)
我们这里统一设置为两个交点,一个交点为start,一个交点为end。
再进行遍历操作。
用vis[]数组记录当前岛屿是否已经被雷达检测到。
vis[i] = 1代表已经检测到,不需要再处理了。
反之,vis[i] = 0代表未检测到,需要新的雷达。
如果一个岛屿的end大于另外一个岛屿的start,那么这两个岛屿就可以共享一个雷达。
同理这样推广到多个岛屿,进行相应的处理。
这个就是考虑数学的计算和贪心策略啦~
掌握这两点就比较好解决了。
我先开始WA了几次。就是输出问题。
我以为输出-1是直接输出的,没想到也需要输出Case *:
所以!!!一定要记得,不管能不能检测到所有岛屿,都得输出前面的前缀!!
代码部分:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#define mst(a, n) memset(a, n, sizeof(a))
using namespace std;
const int N = 1e3 + 10;
struct node1
{
int x;
int y;
}island[N];
struct node2
{
double star;
double end;
}rad[N];
bool cmp(node2 a, node2 b)
{
return a.end < b.end;
}
int main()
{
int n, d;
int cas = 1;
while (~scanf ("%d%d", &n, &d) && n && d)
{
int maxxy = 0;
for (int i = 0; i < n; i++)
{
scanf ("%d%d", &island[i].x, &island[i].y);
if (island[i].y > maxxy)
{
maxxy = island[i].y;
}
}
cout << "Case " << cas++ << ": ";
if (maxxy > d || d < 0)
{
cout << "-1\n";
continue;
}
double len;
for (int i = 0; i < n; i++)
{
len = sqrt(1.0 * d * d - 1.0 * island[i].y * island[i].y);
rad[i].star = island[i].x - len;
rad[i].end = island[i].x + len;
}
sort(rad, rad + n, cmp);
int ans = 0;
int vis[N] = {0};
for (int i = 0; i < n; i++)
{
if (!vis[i])
{
vis[i] = 1;
for (int j = 0; j < n; j++)
{
if (!vis[j] && rad[i].end >= rad[j].star)
{
vis[j] = 1;
}
}
ans++;
}
}
cout << ans << endl;
}
return 0;
}