1 条题解
-
0
解析: 按各喷头起点从小到大排序,优先选能覆盖当前起点,且终点最大的。 注意,如果喷洒半径小于W/2,则该喷头可以忽略。
#include<bits/stdc++.h> using namespace std; struct node { double b,e;//每个喷头覆盖的起点和终点 }a[15005]; bool cmp(node x,node y){ return x.b<y.b; } int T; int n,L,W; int main() { cin>>T; while(T--){ cin>>n>>L>>W; for(int i=1;i<=n;i++){ int p,r; cin>>p>>r; a[i].b=0; a[i].e=0; if (r>=W/2.0){ a[i].b=p-sqrt(r*r-W*W/4.0); a[i].e=p+sqrt(r*r-W*W/4.0); } } sort(a+1,a+1+n,cmp);//按起点从小到大排序 int cnt=0;//需要的喷头数量 double s=0;//起点 double t=0;//终点 int i=1;//从第一个喷头开始 bool flag=1;//假定有解 while (t<L){//只要没覆盖完 cnt++;//增加一个喷头 s=t;//起点为上次的终点 for(;a[i].b<=s&&i<=n;i++){//枚举可以覆盖起点的喷头 t=max(t,a[i].e);//找到最大覆盖的终点 } if(s==t&&t<L){//如果没有覆盖起点的喷头并且终点没有覆盖整个区间 flag=0; cout<<-1<<endl;//无解 break; } } if (flag==1){//有解 cout<<cnt<<endl; } } return 0; }
信息
- ID
- 608
- 时间
- 1000ms
- 内存
- 512MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者