C

C - 安装雷达

Time Limit: 1000/1000MS (C++/Others) Memory Limit: 65536/65536KB (C++/Others)

Problem Description

我们假设海岸线是一条无限直线:以海岸线为界,陆地和海洋被分开,在海边分布着很多小岛。现在,我们在海岸线上安装雷达,每个雷达有固定的通讯范围(以d为半径的圆形区域),这样,海边的小岛就可以被某个雷达信号覆盖。
这里我们使用笛卡尔坐标系,定义海岸线为x轴,x轴上方是海洋,下方是陆地。给出分布在海边每个小岛的坐标位置和雷达信号能覆盖的范围d,你的任务是计算出最小需要安装的雷达数目,使得这些雷达信号能覆盖到所有海边的小岛。每个小岛的坐标格式为(x,y)。
如下图所示,给出第一个输入样例的坐标表示,这样在(-2,0),(1,0)上分别安装雷达就可以覆盖所有的小岛(p点),所以我们只需要安装2个雷达。

Input

输入包含多组测试样例。每组测试第一行包含两个整数n(1<=n<=1000)和d,n表示小岛的数目,d表示雷达能覆盖的范围的半径。接下来n行,每行由整数x和y组成,表示n个小岛的坐标位置。每两组数据之间有一个空行。
输入0 0表示输入的结束。

Output

对于每一组输入,按照输出样例中的格式输出:包含输出序号和最少需要安装雷达的数目。如果找不到解决方案,即不能找到一种安装方案覆盖所有的小岛,输出”-1”。

Sample Input

3 2
1 2
-3 1
2 1

1 2
0 2

0 0

Sample Output

Case 1: 2
Case 2: 1





#include<cstdio>
#include<cmath>
#include<algorithm>
#define fi first  // 宏定义 为了代码简便
#define se second // 分别表示pair中的第一个数和第二个数
using namespace std;
const int maxn = 1e5+5;

pair<double, double> a[maxn];

int main()
{
    int n, d, cs = 1;
    while(~scanf("%d%d", &n, &d) && n){
        double x, y;
        bool can = true;
        for(int i=0; i<n; i++){
            scanf("%lf%lf", &x, &y);
            if(y > d || y < -d) { // 无法覆盖的点
                can = false;
                continue;
            }
            a[i].fi = x - sqrt(d*d - y*y); // 可覆盖第i个点,在x轴上最左侧的位置
            a[i].se = x + sqrt(d*d - y*y); // 可覆盖第i个点,在x轴上最右侧的位置
        }

        printf("Case %d: ", cs++);
        if(!can) {
            puts("-1");
            continue;
        }

        int cnt = 1;
        sort(a, a+n); // 默认按照第一个数升序优先,第二个数升序的顺序排序
        pair<double, double> now = a[0]; // 初始化可用区间
        for(int i=1; i<n; i++){
            if(now.se < a[i].fi) { // 当前区间不能覆盖a[i] 更新可能区间
                cnt ++;            
                now = a[i];
            }
            else if(now.se > a[i].se) now = a[i]; // 当前区间过大,需要减小可用区间
        }
        printf("%d
", cnt);
    }


    return 0;
}
原文地址:https://www.cnblogs.com/yangf428/p/10180712.html