poj1328:
Radar Installation
题目描述:
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.
假设陆地的海岸线是一条无限延长的直线,海岛是一个个的点,现需要在海岸线上安装雷达,使整个雷达系统能够覆盖到所有的海岛。雷达所能覆盖的区域是以雷达为圆心半径为d的圆,我们用指标坐标系来描述,海岸线就是x轴,现在给出每个海岛的坐标与雷达的半径d,请编写一个程序计算出最少需要多少个雷达才能够将所有海岛全部覆盖?
输入:
输入将会有多组数据,每组数据第一行为n (1<=n<=1000),d,n为海岛个数,d为雷达半径,接下来n行,每行两个数描述海岛坐标。以n==0,d==0表示输入结束
输出:
每组数据对应一行,输出最少需要的雷达个数,如果不能满足,则输出-1。
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
typedef struct
{
double left;
double right;
}point;
point p[1001];
int n, d, sum;
/* 按左坐标递减排序 */
int cmp(const void *a, const void *b)
{
return (*(point*)a).left >= (*(point*)b).left ? 1 : -1;
}
void Solve()
{
int i;
double std;
/* 对岛坐标进行排序 */
qsort(p, n, sizeof(point), cmp);
sum = 1;
/* 标准值为第一个点右坐标 */
std = p[0].right;
/* 从最左边开始扫描 */
for (i = 1; i < n; i++)
{
/* 某点左坐标比标准值大则雷达 + 1,更新标准值为该点右坐标 */
if (p[i].left > std)
{
std = p[i].right;
sum++;
}
else
{
/* 某点右坐标比标准值小,更新标准值为该点右坐标 */
if (p[i].right < std)
{
std = p[i].right;
}
}
}
}
int main()
{
int x, y, i, t, fail;
double l;
t = 1;
while(1)
{
fail = 0;
scanf("%d%d", &n, &d);
if(n + d == 0) break;
for (i = 0; i < n; i++)
{
scanf("%d%d", &x, &y);
/* 若岛超出雷达范围则标记失败 */
if (y > d)
{
fail = 1;
}
else
{
/* 求出雷达范围X轴方向上岛的临域 */
l = sqrt((double)(d * d - y * y));
/* 岛可安雷达的最左坐标 */
p[i].left = x - l;
/* 岛可安雷达的最右坐标 */
p[i].right = x + l;
}
}
if (fail)
{
sum = -1;
printf("Case %d: %d\n", t++, sum);
}
else
{
Solve();
printf("Case %d: %d\n", t++, sum);
}
}
//system("pause");
return 0;
}
代码可以在VC++6.0中正确运行,也可以在poj中正确运行。