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 }