地址:http://poj.org/problem?id=1328
题意:在一个笛卡尔坐标系中有一些点(岛屿且其y坐标都大于零),在x轴上确定安装雷达的点,这些点的覆盖范围是给定半径的圆,至少要安装多少雷达可以覆盖所有岛屿,若无解则输出-1.
思路:从每一个岛屿入手,以岛屿为圆心雷达覆盖半径为半径画圆,与x轴交一个区间,显然这个区间内任意一点安设雷达都可以覆盖这个岛屿,那么问题便转化成了这些区间之间的关系。
解法:
1.先将各点以x坐标递增排序,算出各区间左右值left[i],right[i].
2.先将雷达temp安装在right[i]上,若left[i+1]<temp<right[i+1],显然可以覆盖下一个岛屿。若left[i+1]>temp显然需要增设雷达,雷达计数+1,temp右移至right[i+1]。还有一种情况,即right[i+1]<temp,这是由于y值不同可能存在的,但显然left[i]<left[i+1],此时需要将temp左移至right[i+1]。遍历所有区间可得结果。
#include<iostream>
#include<cmath>
using namespace std;
#define N 1005
int main()
{
int n,i,j,count,t;
t=1;
int flag;
double x[N],y[N];
double left[N],right[N];
double r,tx,ty,temp;
while(cin>>n>>r&&n&&r)
{
count=1;
flag=0;
for(i=0;i<n;i++)
{
cin>>x[i]>>y[i];
if(y[i]>r) flag=1;
}
if(flag)
{
cout<<"Case "<<t<<": -1"<<endl;
t++;
continue;
}
for(i=0;i<n-1;i++)
for(j=0;j<n-i-1;j++)
{
if(x[j]>x[j+1])
{
tx=x[j];
ty=y[j];
x[j]=x[j+1];
y[j]=y[j+1];
x[j+1]=tx;
y[j+1]=ty;
}
}
for(i=0;i<n;i++)
{
left[i]=x[i]-sqrt(r*r-y[i]*y[i]);
right[i]=x[i]+sqrt(r*r-y[i]*y[i]);
}
temp=right[0];
for(i=1;i<n;i++)
{
if(temp<left[i])
{
temp=right[i];
count++;
}
else
{
if(temp>right[i])
temp=right[i];
}
}
cout<<"Case "<<t<<": "<<count<<endl;
t++;
}
return 0;
}