题意:
一片长为L宽为W的矩形草坪,然后给出n个喷头的圆心坐标和半径,问你最少需要几个喷头可以覆盖整个草坪。
思路:
刚开始的时候直接觉得可以算出每个喷头可以覆盖的区间,然后就变成前面刚做过的区间覆盖问题了;后面看了一下样例,发现这样想是不对的,因为喷头边沿的圆弧可能是不能完全覆盖住草地的,所以那些地方就必须还要别的喷头去覆盖,这样就不能直接用区间合并来做了。后面又想了一下,其实每个喷头覆盖的有效区域就是一个矩形,我们只需要求出每个喷头覆盖的有效区域(就是矩形完全包含在圆内的部分,用简单的几何知识算一下就可以得到的),就又变成区间覆盖问题了!有一点需要注意:如果一个喷头的半径不大于矩形宽度一半的话,那么这个喷头可以覆盖的有效区域为0(相当于这个矩形的内接圆),我们可以忽略这些喷头。
代码如下:
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; typedef struct { double x,y; }P; P p[11000]; int cmp(P p1,P p2) { return p1.x<p2.x; } int main() { int i,j,k,n; double len,w; while(scanf("%d%lf%lf",&n,&len,&w)!=EOF) { k=0; for(i=0;i<n;i++) { double x1,r; scanf("%lf%lf",&x1,&r); if(r<=w/2) continue; p[k].x=x1-sqrt(r*r-w*w/4); p[k].y=x1+sqrt(r*r-w*w/4); k++; } sort(p,p+k,cmp); int cnt=0,flag=0; double left=0; for(i=0;i<k;) { double max1=0; while(p[i].x<=left&&i<k) { if(p[i].y>max1) max1=p[i].y; i++; } if(max1==0) break; cnt++; left=max1; if(left>=len) { flag=1; break; } } if(flag) printf("%d\n",cnt); else printf("-1\n"); } return 0; }
时间: 2024-10-27 19:04:59