POJ 1328 岛屿雷达问题 贪心

本文介绍了一种算法,用于解决在给定岛屿坐标和雷达覆盖范围的情况下,如何最小化所需雷达数量的问题。通过将问题转化为计算海岸线上雷达覆盖区间的交集,实现了有效求解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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. 

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

题目大意 给你一些岛屿的坐标和雷达的半径 要你求出覆盖所有的点所需要的雷达的最少的数目
 
我的思路 可以先求出以每个岛屿为圆心 雷达半径为半径的圆与海岸线相截的区间 然后求出相互重叠的区间有哪些
需要注意的是 特殊的情况 比如有些岛屿到海岸的直线距离就是雷达半径 这种情况必须要在切点设置一个雷达
所以要判断切点是不是在相交区间内

emmm不过我写错了 我觉得我的思路应该没有错误
另外注意一些细节 雷达半径是负数什么的 然后点的坐标不一定都是整数

#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>

typedef struct tagLINE{
	double left;
	double right;
}Line;
void sortLineBuf(Line *p, int num)
{
	Line temp;
	for (int i=0; i<num; ++i)
	{
		for (int j=i+1; j<num; ++j)
		{
			if (p[j].left < p[i].left){
				temp = p[i];
				p[i] = p[j];
				p[j] = temp;
			}
		}
	}
}
int main()
{
	int caseNum = 0;
	double tempPoint;
	Line tempLine;
	while (true)
	{
		int islandNum = 0, r = 0;
		scanf("%d%d", &islandNum, &r);
		if (islandNum == 0 && r == 0) break;

		double *p = (double*)malloc(sizeof(double) * islandNum * 2);
		double *pX = p;
		double *pY = p+islandNum;
		for(int i=0; i<islandNum; ++i){
			scanf("%lf%lf", &pX[i], &pY[i]);
		}
		//
		int rapar = 0;
		bool bImpossible = true;
		Line* pLine = (Line*)malloc(sizeof(Line) * islandNum);
		//1 转换为直线
		for(int i=0; i<islandNum; ++i){
			if (fabs(pY[i]) > r){
				bImpossible = false;
				rapar = -1;
				break;
			}
			tempPoint = sqrt(r*r - pY[i]*pY[i]);
			pLine[i].left = pX[i]-tempPoint;
			pLine[i].right = pX[i]+tempPoint;
		}
		if (bImpossible)
		{
			rapar = 1;
			//2
			sortLineBuf(pLine, islandNum);
			//3 求解线段交集
			tempLine = pLine[0];
			for (int i=1; i<islandNum; ++i)
			{
				if (pLine[i].left > tempLine.right)
				{
					++rapar;
					tempLine = pLine[i];
				}
				else if (pLine[i].right < tempLine.right)
				{
					tempLine = pLine[i];
				}
			}
		}
		printf("Case %d: %d\n", ++caseNum, rapar);
		free(p);
		free(pLine);
	}

	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值