POJ
来源:互联网 发布:网络电视机顶盒功能 编辑:程序博客网 时间:2024/05/17 07:04
问题描述
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.
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.
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 21 2-3 12 11 20 20 0
Sample Output
Case 1: 2Case 2: 1
分析
先解释一下这个题目,意思就是在x轴上安放雷达,每一个雷达覆盖的范围是一个以d为半径的圆。在海上(y>0)的区域内有n个岛屿,要求安放最少的雷达覆盖所有的岛屿。
首先我自己分析这个题目的时候想到了POJ-3069这个题目,题目大意就是在一条直线上(一维空间),有多个点,然后给它们加上标记,对每个点,其距离为R以内的区域内必须有标记的点,求最少的标记点数目。想了半天啊,发现根本不是这个思路,虽然也相当于在x轴这条线上找标记点,但是它覆盖的区域是二维空间里的点,这样无法按照一维的先排序再贪心。
所以换思路,它要求在x轴上找点作为雷达,这个点肯定在一个区间内都可以覆盖到某个岛屿,那么就利用一下简单的平面几何知识,以岛屿为圆心,d为半径画圆,交于x轴两点,那么这两点就是雷达可覆盖到此岛屿的区间范围,那么把所有的岛屿都如此操作,并将区间存放,这样如果有多个岛屿的区间有相交的部分,那么雷达就可以放在相交的区间内,这样此雷达就可以覆盖到多个岛屿了,也就转换为最大不相交覆盖问题。
注意,如果d < 0 , 或者一个岛屿的y<0(题目要求岛屿只能在海域) ,或者某个岛屿的y > d(这样x轴上不可能有雷达能覆盖到此岛屿),这些情况都是无法解决的,输出-1。PS:在这上面wa了好多次。
#include<cstdio>#include<algorithm>#include<cmath>using namespace std;const int maxn = 1000+10;int n, d;struct Island{ double x,y;}island[maxn];struct Interval{ double start, end;}a[maxn];int cmp(const Interval &a, const Interval &b){ if(a.end < b.end) return 1; else if(a.end == b.end && a.start < b.start) return 1; else return 0;}/*找圆与x轴交点的左端点*/double left_x(double x, double y){ double x_len = sqrt(d*d - y*y); return x-x_len;}/*找圆与x轴交点的右端点*/double right_x(double x, double y){ double x_len = sqrt(d*d - y*y); return x+x_len;}/*最大不相交覆盖的解决*/void solve(){ sort(a, a+n, cmp); double e = a[0].start - 1; int count = 0; for(int i=0; i<n; i++) { if(a[i].start > e) { count++; e = a[i].end; } } printf("%d\n",count); return;}int main(){ int k = 0; while(scanf("%d%d",&n, &d)!=EOF) { int ok = 1; if(n == 0 && d == 0) break; for(int i=0; i<n; i++) { scanf("%lf%lf",&island[i].x, &island[i].y); if(island[i].y > d || island[i].y < 0) ok = 0;//注意细节 a[i].start = left_x(island[i].x, island[i].y); a[i].end = right_x(island[i].x, island[i].y); } if(!ok) printf("Case %d: -1\n",++k); else{ printf("Case %d: ",++k); solve(); } } return 0;}
- POJ
- poj
- POJ
- POJ
- poj
- poj
- POJ
- POJ
- poj
- POJ
- POJ
- POJ
- POJ
- POJ
- POJ
- POJ
- POJ
- POJ
- PHP中error_reporting()用法详解
- hrbust 哈理工 oj 1585 公主之魔镜魔镜 (优先队列)
- NA阶段七种LSA
- 题目1190:大整数排序 九度OJ
- 企业背后的推手—数据可视化软件
- POJ
- C51单片机 AT89S52 定时器使用方法及总结
- 大数据学习网站
- 2017春招——今日头条——android岗
- JavaScript学习笔记16-if嵌套
- JS封装通过className获取元素的函数
- hrbust 哈理工oj 1176 小陈老师、雪人(优先队列)
- ESP8266接线接线说明
- php表单验证