poj 1328 Radar Installation

Radar Installation
Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 47664 Accepted: 10626

Description

Assume the coasting is an infinite straight line. Land is in one side of coasting, sea in the other. Each small island is a point locating in the sea side. And any radar installation, locating on the coasting, can only cover d distance, so an island in the sea can be covered by a radius installation, if the distance between them is at most d. 
假设海岸线是一个无限直线。陆地在海岸线的一边,海在另一侧。每一个小岛都是一个点,位于海的那边。然后雷达都安装在海岸线上,只能覆盖距离d,所以一个小岛在海上能够被雷达覆盖,除非他到雷达的距离小于等于d。 
We use Cartesian coordinate system, defining the coasting is the x-axis. The sea side is above x-axis, and the land side below. Given the position of each island in the sea, and given the distance of the coverage of the radar installation, your task is to write a program to find the minimal number of radar installations to cover all the islands. Note that the position of an island is represented by its x-y coordinates. 
我们使用直角坐标系,定义海岸线是x轴。海在x轴上方,x轴下面是陆地。给出各岛屿的未知,并给出了雷达的安装覆盖的距离,你的任务是写一个程序,找出雷达装置的最小数目,以覆盖所有的岛屿。请注意,一个岛的位置由它的xy坐标来表示。

 
Figure A Sample Input of Radar Installations


Input

The input consists of several test cases. The first line of each case contains two integers n (1<=n<=1000) and d, where n is the number of islands in the sea and d is the distance of coverage of the radar installation. This is followed by n lines each containing two integers representing the coordinate of the position of each island. Then a blank line follows to separate the cases. 
输入有若干组测试案例。每种情况下的第一行包含两个整数n(1<= n<= 1000)和d,n表示有多少岛屿,d表示雷达的有效距离。然后n行是岛屿的坐标,之后每组之间用一个空行隔开。
The input is terminated by a line containing pair of zeros 

Output

For each test case output one line consisting of the test case number followed by the minimal number of radar installations needed. "-1" installation means no solution for that case.

Sample Input

3 2
1 2
-3 1
2 1

1 2
0 2

0 0

Sample Output

Case 1: 2
Case 2: 1

Source


快排加贪心,因为快排是自己写的,所以效率没有sort高,不过不用考虑cmp写的过程中需要强制转换double,其实如果用结构体保存,也就不用想那么多了。。。。然后贪心,首先将岛屿按x坐标排序,然后根据半径计算出来每个岛屿在x轴上的投影,记录投影左坐标和右坐标,然后首先雷达放在第一个岛屿的右投影坐标上,如果下一个岛屿的左坐标比雷达坐标大,则雷达坐标更新到下一个岛屿的右坐标,并增加一个雷达,如果小,则判断,下一个岛屿的右坐标比当前岛屿的右坐标大还是小,如果大,则不用管,当前雷达能覆盖,如果小,则更新当前雷达坐标为下一个岛屿的右坐标,画图可知。
#include <iostream>
#include<algorithm>
#include <stdio.h>
#include <string.h>
#include <math.h>

using namespace std;

struct Coodi{
    double x;
    double y;
}coodi[1111];

void qsort(int p, int r);
int partition_q(int p, int r);

int main()
{
    int n, d, case_n = 0, flag;
    double left[1111], right[1111], temp;
    int i, j, counter;
    freopen("in.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);

    while(scanf("%d%d", &n, &d) && !(n == 0 && d == 0)){
        case_n ++;
        flag = 0;
        for (i = 0;i < n;i ++){
            scanf("%lf%lf", &coodi[i].x, &coodi[i].y);
            if (coodi[i].y > d){
                flag = 1;
            }
        }
        if (flag){
            printf("Case %d: -1\n", case_n);
            continue;
        }
        qsort(0, n-1);
//        for (i = 0;i < n;i ++){
//            printf("%d = %lf %lf\n", i, coodi[i].x, coodi[i].y);
//        }
        for (i = 0;i < n;i ++){
            left[i] = coodi[i].x - sqrt(d * d - coodi[i].y * coodi[i].y);
            right[i] = coodi[i].x +  sqrt(d * d - coodi[i].y * coodi[i].y);
        }

        temp = right[0];
        counter = 1;
        for (i = 0;i < n - 1;i ++){
            if (left[i+1] > temp){
                temp = right[i+1];
                counter ++;
            }else if (right[i+1] < temp){
                temp = right[i+1];
            }
        }
        printf("Case %d: %d\n", case_n, counter);
    }
    return 0;
}

void qsort(int p, int r){
    int q;
    if (p < r){
        q = partition_q(p, r);
        qsort(p, q-1);
        qsort(q+1, r);
    }
}

int partition_q(int p, int r){
    int i = p - 1;
    int j;
    struct Coodi temp;
    for (j = p;j < r;j ++){
        if (coodi[j].x < coodi[r].x){
            i ++;
            temp = coodi[i];coodi[i] = coodi[j];coodi[j] = temp;
        }
    }
    temp = coodi[i+1];coodi[i+1] = coodi[r];coodi[r] = temp;
    return i + 1;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值