Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 48402 | Accepted: 10768 |
Description
Input
Output
Sample Input
3 2 1 2 -3 1 2 1 1 2 0 2 0 0
Sample Output
Case 1: 2 Case 2: 1
题意:有一个平面坐标,当前假设 x 轴上方为大海,在海上有 n 座岛屿,需要在海岸线上( x 轴)建造一个个雷达去覆盖海上的岛屿,而且雷达都是统一的,具有相同的覆盖面积,其半径为 d,要求输出能覆盖所有岛屿的最小雷达数,未满足要求时输出 -1 。思路:想法很简单,就是贪心的思路,一个圆尽量覆盖更多的点(岛屿)。
只需要将点的坐标按 x 进行排序,先处理左边的点,依次往右边处理。
有两个地方需要注意一下:
1、如下图:
#include <stdio.h> #include <algorithm> #include <math.h> using namespace std; // 岛屿对象 struct coordinate { // 坐标、与 X 轴相交线段的起/终点 double x, y; double s, e; bool operator<(const coordinate &o) const { return e < o.e; } } island[1001]; int solve(int n, int d) { // 计算相交线段起/终点 for (int i = 0; i < n; ++i) { double t = sqrt(d - island[i].y * island[i].y); island[i].s = island[i].x - t;//左侧 island[i].e = island[i].x + t;//右侧 } // 依线段终点排序 sort(island, island + n); // 最少雷达数量(特殊情况已在输入时排除掉, // 程序执行到这里时,至少存在一个合法岛屿, // 故 ans 初始为 1) int ans = 1; double r = island[0].e; // 从第二座岛屿开始扫描,如前一雷达设置点 // 覆盖不到,则雷达数加 1 for (int i = 1; i < n; ++i) { if (island[i].s > r) { ++ans; r = island[i].e; } } return ans; } int main() { int c = 1; int n, d; while (scanf("%d %d", &n, &d) && (n || d)) { bool np = false; for (int i = 0; i < n; ++i) { scanf("%lf %lf", &island[i].x, &island[i].y); if (island[i].y > d) { np = true; } } if (np) printf("Case %d: %d\n", c, -1); else // 直接传入半径平方,减少重复计算 printf("Case %d: %d\n", c, solve(n, d * d)); ++c; } return 0; }
POJ 1328 Radar Installation 贪心,布布扣,bubuko.com
POJ 1328 Radar Installation 贪心
原文:http://blog.csdn.net/zzucsliang/article/details/23689579