貌似本题数据类型也挺重要的,没有具体测试了,就直接用double了,一开始存x, y的时候用的是int,结果wa了,可是之后改成了double还wa,才发现其实是贪心的时候排序出错了。。。。
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
struct Island {
double x, y;
double max, min;
}island[1000];
/* 贪心思想,很多情况下是考虑极值,本题也正是先将每个island的区间求出来,什么是区间?
* 其实就是在海岸边(也就是x轴上)的范围内任何一个位置放置一个雷达都能够覆盖到这个岛,就称
* 这个岛的区间!
*/
/**
* 比较函数。 选用什么排序是关键,一开始错误地选择了横坐标x排序,结果数据基本对的上,
* 仔细一想其实应该是要用每个island的左右闭区间端点排序才对。 第二次选择的时候,又
* 错误地选择了右区间端点,其实应该选择左端点,从我下面的贪心的具体算法可以看出,其实
* 我是用min(左端点)去确保从右往左的所有island能够covered。
*/
int cmp(const Island &a, const Island &b) {
return a.min < b.min;
}
int main()
{
int n, cases = 1, count;
char isOk;
double d;
while(scanf("%d%lf", &n, &d), n) {
isOk = 0;
count = 1;
int i;
for(i = 0; i < n; i ++) {
scanf("%lf%lf", &island[i].x, &island[i].y);
if(island[i].y > d || island[i].y < 0) {
isOk = 1;
}
island[i].max = island[i].x + sqrt(d * d - island[i].y * island[i].y);
island[i].min = island[i].x - sqrt(d * d - island[i].y * island[i].y);
}
if(isOk == 1) {
printf("Case %d: -1\n", cases);
cases ++;
continue;
}
sort(island, island + n, cmp);
double min;
int j = n - 1;
/* 关键是 当 island[j].max < min 的时候,是指从右往左一个个island扫描的时候,保证每个都能覆盖到,而且是用最少的雷达数。 */
for(i = j; i >= 0; i --, i = j) {
min = island[i].min;
for(j = i - 1; j >= 0; j --) {
if(island[j].max < min) {
count ++;
break;
}
}
}
printf("Case %d: %d\n", cases, count);
cases ++;
}
return 0;
}