- 输入
- 第一行输入一个正整数N表示共有n次测试数据。
每一组测试数据的第一行有三个整数n,w,h,n表示共有n个喷水装置,w表示草坪的横向长度,h表示草坪的纵向长度。
随后的n行,都有两个整数xi和ri,xi表示第i个喷水装置的的横坐标(最左边为0),ri表示该喷水装置能覆盖的圆的半径。 - 输出
- 每组测试数据输出一个正整数,表示共需要多少个喷水装置,每个输出单独占一行。
如果不存在一种能够把整个草坪湿润的方案,请输出0。 - 样例输入
-
2 2 8 6 1 1 4 5 2 10 6 4 5 6 5
- 样例输出
-
1 2
这个题我做了两三天一直是wa,基本思路很简单,贪心。用勾股定理求出能覆盖的左右范围,然后从小到大给左端点排序。
一不小心,但总是出现各种各样的错误,被坑死了。
代码如下。
#include<stdio.h> #include<algorithm> using namespace std; #include<math.h> #include<string.h> struct note { double xi,ri; } q[10050]; struct doll { double star,end; } r[10050]; int fun(doll a,doll b) { return a.star<b.star; } int main() { int m; scanf("%d",&m); while(m--) { double w,h,t; int n,i,j,f=1,sum=0; scanf("%d%lf%lf",&n,&w,&h); j=0; for(i=0; i<n; i++) { scanf("%lf%lf",&q[i].xi,&q[i].ri); if(q[i].ri>=(h/2)) { t=sqrt(q[i].ri*q[i].ri-(h/2)*(h/2)); r[j].star=q[i].xi-t; r[j++].end=q[i].xi+t; } } sort(r,r+j,fun); double l=0,max; while(l<w) { max=0; for(i=0; i<n&&r[i].star<=l; i++) { if((r[i].end-l)>max) //每次循环均找出最大的覆盖范围。 { max=r[i].end-l; } } if(max==0) { f=0; break; } else { l=max+l; sum++; } } if(f==1) { printf("%d\n",sum); } else { printf("0\n"); } } return 0; }