//题意:给定岛的数量和坐标,求实现覆盖所有岛的最少的雷达数
//poj1328 前期考虑得太简单,以为只需要满足一个点,后面就自动满足。
//活动选择是在一段时间内尽可能多的安排不冲突的活动
//最后想起了重复段,又想起了小优 poj1083 每个点都有一段覆盖的地方 最大的重复覆盖的地方可以建立一个雷达
//继续优化想法:排序,从左往右看,当区间左端点大于右边所有区间的最小右端点时,答案加一,摒弃前面区间,递归重复。
#include <iostream>
#include <cmath>
#include <string>
using namespace std;
double x[1005];
double y[1005];
bool mark[1005];
int n;
double d;
bool allCover(int n, double d)
{
for(int i = 0; i < n; i++)
{
if(y[i] > d)
return false;
}
return true;
}
int deal(int s, int e)
{
if(s == e - 1)
return 1;
double rightMin = x[s] + sqrt(d * d - y[s] * y[s]);
int j;
for(j = s + 1; j < e; j++)
{
if(x[j] - sqrt(d * d - y[j] * y[j]) <= rightMin)
{
if(x[j] + sqrt(d * d - y[j] * y[j]) < rightMin)
rightMin = x[j] + sqrt(d * d - y[j] * y[j]);
}
else
return 1 + deal(j, e);
}
if(j == e)
{
return 1;
}
}
int main()
{
cin>>n>>d;
int k = 1;
while(n && d){
memset(x, 0, sizeof(x));
memset(y, 0, sizeof(y));
memset(mark, 0, sizeof(mark));
for(int i = 0; i < n; i++){
cin>>x[i]>>y[i];
}
//先判断是否会出现不能覆盖都的岛屿
if(allCover(n, d))
{
int ans = 0;
for(int i = 0; i < n - 1; i++)
{
for(int j = 0; j < n - i - 1; j++)
{
if(x[j] > x[j+1])
{
double temp = x[j+1];
x[j+1] = x[j];
x[j] = temp;
temp = y[j+1];
y[j+1] = y[j];
y[j] = temp;
}
}
}
ans += deal(0, n);
cout<<"Case "<<k++<<": "<<ans<<endl;
}
else
{
cout<<"Case "<<k++<<": "<<-1<<endl;
}
cin>>n>>d;
}
return 0;
}
poj1328 递归+区间覆盖问题
最新推荐文章于 2021-11-24 10:29:12 发布