此題鏈接:點擊打開鏈接
題目大意是給出島嶼的數量n和雷達的覆蓋半徑d,然後給出n組島嶼座標,問最少需要多少雷達可以覆蓋所有島嶼。
這個題可以換個思路(並沒有思路),通過島的座標(直角邊)和雷達半徑(斜邊)求出雷達所能覆蓋此島可能所在的區間,算是個區間覆蓋問題。這樣將區間尾端 按從小到大排序後找到第一個區間的尾端作爲第一個雷達的位置,這樣才能保證覆蓋到最外端的島嶼,遍歷一遍所有區間,若區間前端比雷達位置靠後,則雷達無法覆蓋, 雷達數加一,新雷達位置爲此區間的尾端。
這個題坑不少,首先d可以是負的,這樣就沒了,y>d也是不可以的,這兩種情況要在輸入的時候判斷一下,除了n,d和一些常用變量是int外,其他都要用double存。
//264K 47MS
//C++ 1126B
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
struct node
{
double b,d;
}a[1123];
int cmp(node a,node b)
{
return a.d<b.d;
}
int main()
{
int i,n,d,l=0,k;
double x,y;
while(scanf("%d%d",&n,&d)&&(n||d))
{
l++;
k=0;
int sum=1;
for(i=0;i<n;i++)
{
cin>>x>>y;
if(y>d||d<0) //覆蓋半徑爲負或有覆蓋不到的點則標記
{
k=1;
}
a[i].b=x-sqrt(d*d-y*y);//記錄區間前端位置
a[i].d=x+sqrt(d*d-y*y);//記錄區間尾端位置
}
if(k) //出現上面的情況直接輸出-1
{
printf("Case %d: -1\n",l);
}
else
{
sort(a,a+n,cmp); //按區間尾端升序排序
double f=a[0].d; //當前雷達位置爲第一個區間的尾端
for(i=1;i<n;i++)
{
if(a[i].b>f) //若此雷達不在該區間內
{
sum++; //雷達數加一
f=a[i].d; //更新雷達位置
}
}
printf("Case %d: %d\n",l,sum);
}
}
return 0;
}