C++基站安装

3 篇文章 0 订阅
3 篇文章 0 订阅

从前有一个一望无际的海滩,海滩后面是陆地,前面是广阔的大海。海中有很多小岛(可以用一个点表示)。现在海滩上需要安装一些基站(海滩上的任意位置)这样岛上的居民就能用手机通话了,所有的基站的覆盖距离都是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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值