假設陸地的海岸線是一條無限延長的直線,海島是一個個的點,現需要在海岸線上安裝雷達,使整個雷達系統能夠覆蓋到所有的海島。雷達所能覆蓋的區域是以雷達爲圓心半徑爲d的圓,我們用指標座標系來描述,海岸線就是x軸,現在給出每個海島的座標與雷達的半徑d,請編寫一個程序計算出最少需要多少個雷達才能夠將所有海島全部覆蓋?
輸入:
輸入將會有多組數據,每組數據第一行爲n (1<=n<=1000),d,n爲海島個數,d爲雷達半徑,接下來n行,每行兩個數描述海島座標。以n==0,d==0表示輸入結束
輸出:
每組數據對應一行,輸出最少需要的雷達個數,如果不能滿足,則輸出-1,具體格式見樣例。
樣例輸入:
3 2
1 2
-3 1
2 1
1 2
0 2
0 0
樣例輸出:
Case 1: 2
Case 2: 1
題很坑!大致思路就是把每個點轉換爲一條條線段,用區間選點的方法做,很坑,具體見代碼。
<pre name="code" class="cpp">#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<math.h>
using namespace std;
struct seg{
double a,b;
}x[1001];//每一條線段
int n;
double d;
bool cmp(seg a,seg b)
{
if(a.b!=b.b)return a.b<b.b;
return a.a>b.a;
}//按照每一條線段的右端點排序
int work(double a,double b,int i)
{
if(b>d||b<-d)return 1;//雷達不能覆蓋
double dis=sqrt(d*d-b*b);
x[i].a=a-dis,x[i].b=a+dis;
return 0;
}
int main()
{
int num=0;
while(cin>>n>>d)
{
num++;
int i,cnt=0,f=0,f1;
double j,k;
if(!n&&!d)break;
memset(x,0,sizeof(x));
for(i=1;i<=n;i++)
{
cin>>j>>k;
f1=work(j,k,i);
if(f1)f=1;
}
if(d<0||f)//雷達半徑爲負數......也是不能到達的
{
cout<<"Case "<<num<<": "<<-1<<endl;
continue;
}
sort(x+1,x+n+1,cmp);
double end=-0x3f3f3f3f;//橫座標要很小....因爲..你懂的
for(i=1;i<=n;i++)
{
if(end<x[i].a)
{
end=x[i].b;
cnt++;
}
}
cout<<"Case "<<num<<": "<<cnt<<endl;
}
}