【問題】
長 L 米,寬 W 米的草坪裏裝有 n 個澆灌噴頭。每個噴頭都裝在草坪中心線上(離兩邊各 米)。我們知道每個噴頭的位置(離草坪中心線左端的距離),以及它能覆蓋到的澆灌範圍。
請問:如果要同時澆灌整塊草坪,最少需要打開多少個噴頭?【輸入】
輸入包含若干組測試數據。
第一行一個整數 T 表示數據組數;
每組數據的第一行是整數 n、L 和 W;
接下來的 n 行,每行包含兩個整數,給出一個噴頭的位置和澆灌半徑(上面的示意圖是樣例輸入第一組數據所描述的情況)。【輸出】
對每組測試數據輸出一個數字,表示要澆灌整塊草坪所需噴頭數目的最小值。如果所有噴頭都打開也不能澆灌整塊草坪,則輸出 -1
【思路】
首先計算一下每個噴水裝置的有效覆蓋範圍(因爲是圓形區域,如下圖紅線區域爲有效區域),存入數組中,按照區域首排序。
然後在進行操作,典型的區間覆蓋問題,具體看代碼。
【源代碼】
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 100000+5;
struct Node
{
double pos;
double num;
bool operator < (const Node &b)const
{
return pos< b.pos;
}
} node[N];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n,l,w;
scanf("%d%d%d",&n,&l,&w);
int cnt=0;
for(int i=1; i<=n; i++)
{
int pos,r;
scanf("%d%d",&pos,&r);
if(r>w/2)
{
node[++cnt].pos=pos-sqrt(r*r-(w/2.0)*(w/2.0));
node[cnt].num=pos+sqrt(r*r-(w/2.0)*(w/2.0));
}
}
sort(node+1,node+1+cnt);
double len=0;
int res=0;
bool flag=true;
int i=1;
while(len<l)
{
res++;
double pos=len;
while(node[i].pos<=pos&&i<=cnt)
{
if(len<node[i].num)
len=node[i].num;
i++;
}
if(len==pos&&pos<l)
{
printf("-1\n");
flag=false;
break;
}
}
if(flag)
printf("%d\n",res);
}
return 0;
}