原题
Radar Installation
Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 146022 Accepted: 32155
Description
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.
Figure A Sample Input of Radar Installations
input
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 2
1 2
-3 1
2 1
1 2
0 2
0 0
Sample Output
Case 1: 2
Case 2: 1
Source
Beijing 2002
一、解题思路
示例:可将问题转化为以小岛为圆心,半径为雷达半径,求出其与x轴的交点(s[i].left,s[i].right),
求线段交集的问题,按s[i].left从小到大排序,若i与集合{j,j+1,…,i-1}有交集,
即若s[i].left <= min(s[j].right,s[j+1].right,…,s[i-1].right) 则无需增加雷达,
若没有交集,则增加一个雷达,并更新集合为{i}
如
二、步骤
1.引入库
代码如下(示例):
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<iostream>
using namespace std;
2.定义结构体
代码如下(示例):
struct dir
{
double left,right;
}
3.编写运算符重载函数
bool operator < (const dir &a, const dir &b)
{
return a.left < b.left;
}
4.完整代码如下:
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<iostream>
using namespace std;
struct dir
{
double left,right;
} s[1010];
bool operator < (const dir &a, const dir &b)
{
return a.left < b.left;
}
int main()
{
int n,d,num=0;
int x,y;
while(1)
{
num++;
int flag=1;
scanf("%d%d",&n,&d);
if(n==0 && d==0)
break;
for(int i=0; i<n; i++)
{
scanf("%d%d",&x,&y);
//这里注意,不能漏了情况,y>d则无法覆盖所有小岛 输出-1
if(y>d)
flag=0;
else
{
//使用sqrt大多数时候需要强制类型转换,因为sqrt只支持double,flaot,long double类型
//这里需用double类型强制转化,且left和right也需是double类型否则会造成数据缺失,不能通过oj
s[i].left = x - sqrt((double)d*d - y*y);
s[i].right = x + sqrt((double)d*d - y*y);
}
}
sort(s,s+n);
int count=1;
double minright=s[0].right;
for(int i=1; i<n; i++)
{
if(s[i].left > minright)
{
count++;
minright=s[i].right;
}
else
{
if(s[i].right < minright)
minright=s[i].right;
}
}
if(flag)
printf("Case %d: %d\n",num,count);
else
printf("Case %d: -1\n",num);
}
return 0;
}
如有不对,欢迎指正。