【题目描述】
长 L 米,宽 W 米的草坪里装有 n 个浇灌喷头。每个喷头都装在草坪中心线上(离两边各 W/2 米)。我们知道每个喷头的位置(离草坪中心线左端的距离),以及它能覆盖到的浇灌范围。如果要同时浇灌整块草坪,最少需要打开多少个喷头?
【题目链接】
https://loj.ac/problem/10002
【算法】
贪心——>区间覆盖问题。注意,半径小于W/2的喷头直接跳过,不然会炸,不要问我是怎么知道的。
【代码】
1 #include <bits/stdc++.h> 2 using namespace std; 3 int T,n,L,W,tot; 4 struct pos{ double b,e; }p[15010]; 5 bool operator < (pos& a,pos& b) { return a.b<b.b; } 6 double calc(int r) { return sqrt(r*r-W*W/4.0); } 7 int main() 8 { 9 scanf("%d",&T); 10 while(T--) { 11 tot=0; 12 scanf("%d%d%d",&n,&L,&W); 13 for(int i=1;i<=n;i++) { 14 int x,r; scanf("%d%d",&x,&r); 15 if(r<=W/2.0) continue; 16 double tmp=calc(r); 17 p[++tot].b=x-tmp; p[tot].e=x+tmp; 18 } 19 sort(p+1,p+tot+1); 20 double s=0.0; 21 int j=1,ans=0,rec; 22 while(s<L&&j<tot) { 23 rec=0; 24 for(;j<=tot;j++) if(p[j].b<=s) { if(p[j].e>p[rec].e&&p[j].e>=s) rec=j; } else break; 25 if(rec) ans++,s=p[rec].e; 26 else break; 27 } 28 if(s>=L) printf("%d ",ans); 29 else puts("-1"); 30 } 31 return 0; 32 }