贪心算法,和《算法艺术与信息学竞赛》上的例题很像。 写起来很容易,但不知道修改了无数次,考虑了精度以后还是WA。 #include <stdio.h> #include <stdlib.h> #include <math.h> #define MAXISLAND 1001 #define MAXSEG 1001 #define INFINITY -1000000 /* 经过观察,发现以小岛p为圆心,雷达辐射距离d为半径作圆,所得的圆交X轴于x1,x2两点。在线段x1,x2之间任意一点放置 雷达站都能辐射到小岛p。因此在每个线段中只需选择一点放雷达即可满足要求。由贪心思想,选择最靠右的点可以保证雷达数 最少。*/ struct Segment { double left; double right; }seg[MAXSEG]; struct IsLandStruct { int x; int y; }p[MAXISLAND]; int n,d,radionum; int mark[MAXSEG]; int comp(const void *a,const void *b) { struct Segment *p=(struct Segment *)a,*q=(struct Segment *)b; return (p->left-q->left)>1e-7; } int main() { int i,Case=0,flag=0;; double last,delta; freopen("input.in","r",stdin); scanf("%d%d",&n,&d); while (n!=0 || d!=0) { Case++;flag=0; for (i=0;i<n;i++) { scanf("%d%d",&p[i].x,&p[i].y); if (d*d-p[i].y*p[i].y>=0) delta=sqrt(double(d*d-p[i].y*p[i].y)); else { flag=1; break; } seg[i].left=p[i].x-delta; seg[i].right=p[i].x+delta; mark[i]=0; } if (flag) { printf("Case %d: -1/n",Case); scanf("%d%d",&n,&d); continue; } qsort(seg,n,sizeof(seg[0]),comp); for (i=0;i<n-1;i++) if (seg[i].right>=seg[i+1].right+1e-7) mark[i]=1; last=INFINITY;radionum=0; for (i=0;i<n;i++) if (mark[i]==1) continue; else if (last<seg[i].left+1e-7) { last=seg[i].right; radionum++; } printf("Case %d: %d/n",Case,radionum); getchar(); getchar(); scanf("%d%d",&n,&d); } }