无意间发现了一篇poj的题目分类,里面例出了从入门到高级的题目分类....鼎鼎大名的poj分类很好很有层次感=。=
此题为贪心,题目大意是最少用多少个雷达可以覆盖所有的岛屿。雷达在同一条线上,如果存在雷达扫描不到的岛屿那么输出-1。
我们可以把每个岛屿看做一个圆,然后以雷达半径作为半径,记录下每个岛屿在x轴上的最大点与最小点。
如果前一个岛屿在x轴上的最大点大于后一个岛屿在x轴上的最小点,那么在x轴上以岛屿最大点画圆,则必定包含了前后两个岛屿,不需要再增加雷达。
如果前一个岛屿在x轴上的最大点小于后一个岛屿在x轴上的最小点,那么一个雷达是无法同时检测到两个岛屿的,需要雷达+1。
另外,如果一个雷达能检测到多个岛屿,雷达应该取所有岛屿的最小右边界,否则如果下一个点只满足岛屿的雷达检测却不满足含有岛屿最小右边界的检测的话会出错。
代码如下:
//
// main.cpp
// poj1328
//
// Created by Saber on 15/10/7.
// Copyright © 2015年 Saber. All rights reserved.
//
#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstdio>
using namespace std;
const int MAX = 1001;
struct island
{
double left, right;
};
island a[MAX];
int mycmp(const island &a, const island &b)
{
return a.left < b.left;
}
int main()
{
int n, d;
double x1, y1;
int num = 1;
while (~scanf("%d %d", &n, &d) && (n || d))
{
bool flag = true;
for (int i = 0; i < n; i++)
{
scanf("%lf %lf", &x1, &y1);
a[i].left = x1 - sqrt(d*d*1.0 - y1*y1);
a[i].right = x1 + sqrt(d*d*1.0 - y1*y1);
if (fabs(y1) > d)
flag = false;
}
sort(a, a+n, mycmp);
int ans = 1;
island temp = a[0];
for (int i = 1; i < n; i++)
{
if (temp.right < a[i].left)
{
ans++;
temp = a[i];
}
else if (temp.right > a[i].right)
{
temp = a[i];//将雷达位置调换到最小右边界的岛屿,否则WA...
}
}
if (flag)
cout << "Case " << num << ": " << ans <<endl;
else
cout << "Case " << num << ": " << -1 <<endl;
num++;
}
return 0;
}