1328:Radar Installation,考点:贪心策略、覆盖问题

原题:http://bailian.openjudge.cn/practice/1328/

描述

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.

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.

 

 

中文简洁易懂型描述:

输入

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.

The input is terminated by a line containing pair of zeros

输出

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.

样例输入

3 2
1 2
-3 1
2 1

1 2
0 2

0 0

样例输出

Case 1: 2
Case 2: 1

解法

思路:贪心,关键在于找到对什么排序。

首先将岛屿的二维坐标转到与雷达的一维坐标相关。

 

 相当于覆盖问题

 

 

 整个贪心策略如下:

 

 

 

 贪心算法的证明:

 代码如下:

写代码时遇到的坑:1. 没有解法的输出也要等所有输入都读入再输出,不要直接break。2. 区分一下什么时候需要用d,什么时候不用d。

 1 #include <iostream>
 2 #include <cmath>
 3 #include <vector>
 4 #include <algorithm>
 5 using namespace std;
 6 int n, d;
 7 struct point {
 8     double start;
 9     double end;
10     point(int x, int y) {
11         double dx2 = d * d - y * y;
12         double dx = sqrt(dx2);
13         start = x - dx;
14         end = x + dx;
15     }
16     bool operator<(const point A)const {
17         return start < A.start;
18     }
19 };
20 bool cancover(double s, double e, double x) {
21     if (e<x || s>x)
22         return false;
23     else
24         return true;
25 }
26 int main() {
27     int num = 1;
28     while (cin >> n >> d) {
29         if (n == 0)break;
30         vector<point>islands;
31         for (int i = 0; i < n; i++) {
32             int x, y;
33             cin >> x >> y;
34             if (y > d)
35                 continue;
36             islands.push_back(point(x, y));
37         }
38         if (islands.size() < n) {
39             cout << "Case " << num++ << ": -1" << endl;
40             continue;
41         }
42         sort(islands.begin(), islands.end());
43         //unique(islands.begin(), islands.end());
44         int firstNoConverd = 0;
45         int result = 0;
46         for (int i = 1; i < n; i++) {
47             double xi = islands[i].start;
48             for (int j = firstNoConverd; j <= i - 1; j++) {
49                 if (cancover(islands[j].start,islands[j].end,xi))
50                     continue;
51                 //存在一个区间c无法被xi覆盖,放在i-1处
52                 result++;
53                 firstNoConverd = i;
54                 break;
55             }
56         }
57         cout << "Case " << num++ << ": " << ++result << endl;
58     }
59     return 0;
60 }
posted @ 2021-07-14 19:56  永远是个小孩子  阅读(62)  评论(0编辑  收藏  举报