从前有一个一望无际的海滩,海滩后面是陆地,前面是广阔的大海。海中有很多小岛(可以用一个点表示)。现在海滩上需要安装一些基站(海滩上的任意位置)这样岛上的居民就能用手机通话了,所有的基站的覆盖距离都是d,在距离d范围内的小岛都能收到基站发送的信号。
我们用笛卡尔坐标系来表示这个问题,定义x轴为海滩,x轴上方是大海,下方是陆地。现给出每个小岛的位置(用x-y坐标表示)和基站的覆盖范围d,你的任务就是写一个程序,计算出可以覆盖所有的小岛,至少需要在海滩上安装多少基站?
input
输入包含多组数据。对每组数据,第一行包含两个整数n(1 <= n <= 1000)和d,n代表小岛数量,d代表基站的覆盖距离。接下来有n行,每行包含两个整数,表示小岛的位置坐标。输入n=0,d=0时退出。
output
对每组数据,输出包含数据组数,格式如sample,后跟最少需要安装的基站数,如果无解,输出-1。
Sample Input
3 2
1 2
-3 1
2 1
1 2
0 2
1 -2
0 2
0 0
Sample Output
Case 1: 2
Case 1: 2
Case 1: -1
代码:
#include<iostream>
#include<algorithm>
#include<math.h>
using namespace std;
#define MAX 1001
struct TPoint {
int x;
int y;
};
struct TLimit {
double dFrom;
double dTo;
};
TPoint tIsland[MAX];
TLimit tSeg[MAX];
void vInput(int nN);
bool bcheck(int nN, int nD);
void vOut(int nC, int nOut);
void vSort(int nN);
bool bCmp(const TLimit &tA, const TLimit &tB);
int nGetAns(int nN);
int main() {
int nCase;
int nAns;
int nLands, nDist;
nCase = 1;
while (cin >> nLands >> nDist) {
if ((0 == nLands) && (0 == nDist)) {
return 0;
} else {
vInput(nLands);
if (bcheck(nLands, nDist)) {
vSort(nLands);
nAns = nGetAns(nLands);
} else {
nAns = -1;
}
vOut(nCase, nAns);
nCase++;
}
}
return 0;
}
void vInput(int nN) {
int i;
for (i = 1; i <= nN; i++) {
cin >> tIsland[i].x >> tIsland[i].y;
}
}
bool bcheck(int nN, int nD) {
int i;
for (i = 1; i <= nN; i++) {
if (tIsland[i].y > nD) {
return false;
}
tSeg[i].dFrom = tIsland[i].x - sqrt(1.0 * nD * nD - 1.0 * tIsland[i].y * tIsland[i].y);
tSeg[i].dTo = tIsland[i].x + sqrt(1.0 * nD * nD - 1.0 * tIsland[i].y * tIsland[i].y);
}
return true;
}
void vOut(int nC, int nOut) {
cout << "Case " << nC << ": " << nOut << endl;
}
void vSort(int nN) {
sort(&tSeg[1], &tSeg[nN + 1], bCmp);
}
bool bCmp(const TLimit &tA, const TLimit &tB) {
return (tA.dFrom < tB.dFrom);
}
int nGetAns(int nN) {
int nRet;
int i;
double dTemp;
nRet = 1;
dTemp = tSeg[1].dTo;
for (i = 2; i <= nN; i++) {
if (tSeg[i].dFrom > dTemp) {
nRet++;
dTemp = tSeg[i].dTo;
} else {
if (dTemp > tSeg[i].dTo) {
dTemp = tSeg[i].dTo;
}
}
}
return nRet;
}