http://poj.org/problem?id=1328
题意:
假设滑行是无限直线。土地在海岸的一边,海在另一边。每个小岛是位于海边的一个点。位于海岸上的任何雷达装置只能覆盖距离,所以如果两者之间的距离最大为d,则海中的岛屿可以被半径装置覆盖。
我们使用笛卡尔坐标系,定义惯性是x轴。海侧在x轴之上,陆侧在下。考虑到每个岛屿在海洋中的位置,并且考虑到雷达装置的覆盖距离,您的任务是编写一个程序,以找到覆盖所有岛屿的最少数量的雷达装置。注意,岛的位置由其xy坐标表示。
思路:
由于雷达只能处于x轴位置,所以对于每个雷达,我们都可以计算出能覆盖它的雷达的最大区间,即最小最坐标和最大右坐标。
接下来是贪心,按照右坐标从小到大排序,只要区间有交集,就可以用一个雷达来覆盖。
1 #include<iostream> 2 #include<algorithm> 3 #include<cmath> 4 #include<math.h> 5 using namespace std; 6 7 const int maxn = 1000 + 5; 8 9 int d, n; 10 int vis[maxn]; 11 12 struct node 13 { 14 double left, right; 15 }a[maxn]; 16 17 bool cmp(node a, node b) 18 { 19 return a.right < b.right ; 20 } 21 22 double cacl(int y) 23 { 24 return sqrt((double)(d*d - y*y)); 25 } 26 27 int main() 28 { 29 //freopen("D:\\txt.txt", "r", stdin); 30 int x, y, kase = 0; 31 while (cin >> n >> d && n) 32 { 33 memset(vis, 0, sizeof(vis)); 34 int ok = 0; 35 for (int i = 0; i < n; i++) 36 { 37 cin >> x >> y; 38 if (y > d) {ok = 1;} //如果y>d,肯定覆盖不着 39 if (!ok) 40 { 41 double ra = cacl(y); 42 //雷达的左右区域 43 a[i].left = x - ra; 44 a[i].right = x + ra; 45 } 46 } 47 if (!ok) 48 { 49 sort(a, a + n, cmp); 50 int cnt = 0; 51 for (int i = 0; i < n; i++) 52 { 53 if (!vis[i]) 54 { 55 vis[i] = 1; 56 for (int j = 0; j < n; j++) 57 { 58 if (!vis[j] && a[j].left <= a[i].right) 59 vis[j] = 1; 60 } 61 cnt++; 62 } 63 } 64 cout << "Case " << ++kase << ": " << cnt << endl; 65 } 66 else cout << "Case "<<++kase << ": -1" << endl; 67 } 68 return 0; 69 }
时间: 2024-11-02 00:32:38