n sprinklers are installed in a horizontal strip of grass ll meters long and ww meters wide. Each sprinkler is installed at the horizontal center line of the strip. For each sprinkler we are given its position as the distance from the left end of the center line and its radius of operation.
What is the minimum number of sprinklers to turn on in order to water the entire strip of grass?
Input
Input consists of at most 3535 cases. The first line for each case contains integer numbers nn, ll and ww with 1 \le n \le 10\, 0001≤n≤10000, 1 \le l \le 10^71≤l≤107, and 1 \le w \le 1001≤w≤100. The next nn lines contain two integers giving the position xx (0 \le x \le l0≤x≤l) and radius of operation rr (1 \le r \le 1\, 0001≤r≤1000) of a sprinkler.
The picture above illustrates the first case from the sample input.
Output
For each test case output the minimum number of sprinklers needed to water the entire strip of grass. If it is impossible to water the entire strip output -1.
题意:有n个洒水装置,在长度为L宽度为W的草坪上洒水,洒水装置的洒水范围是一个圆,会给出洒水装置的位置x和洒水半径r,问使草坪能全部洒水需要的最少的装置数。不能使草坪全部洒水时候输出-1
思路:首先我们划定草坪的起止位置st,我们要找的就是某个洒水装置满足:洒水装置的左端a<=st。在其基础上找到右端最大的洒水装置,并使其右端成为新的起止位置,往复循环直到起止位置>草坪长度。
其中只需要进行一次排序就可以了,对洒水装置左端点的升序排序,因为我们找到右端作为新起点时,前面的肯定就用不上了。
代码:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=15000+10;
const int mod=998244353;
int dx[]= {1,0,-1,0,1,1,-1,-1};
int dy[]= {0,1,0,-1,1,-1,1,-1};
int n,l,w;
struct Node
{
double a,b;
}s[maxn];
bool cmp(Node a,Node b)
{
return a.a<b.a;
}
void solve()
{
cin>>n>>l>>w;
int m=0;
for(int i=1;i<=n;i++)
{
int x,r;
cin>>x>>r;
if(r<=w/2) continue;
m++;
s[m].a=x-sqrt(r*r-w*w/4.0);
s[m].b=x+sqrt(r*r-w*w/4.0);
}
sort(s+1,s+1+m,cmp);
double st=0;
int ans=0,i=1;
while(st<l)
{
double t=st;
for(;s[i].a<=t&&i<=m;i++)
{
if(s[i].b>=st) st=s[i].b;
}
if(t==st&&t<l)
{
cout<<-1<<endl;
return ;
}
ans++;
}
cout<<ans<<endl;
return ;
}
int main()
{
int t;
cin>>t;
while(t--)
{
solve();
}
}