//题目来源:http://poj.org/problem?id=1328
解题思路:
先讲岛屿按照X坐标,按照升序排列。
计算以岛屿为中心,雷达的有效检测范围为半径,计算出与X轴的交点。
当左边的岛屿,与X轴的交点(靠右的那个交点)>它右边那个岛屿与X轴的交点(靠左边那个),那么雷达装置就可以省一个。
以此类推,就可以计算出所需的雷达数量。
![](https://i-blog.csdnimg.cn/blog_migrate/cdec0645add3fc3c328197dda5c76203.gif)
//POJ1328 //Radar //http://poj.org/problem?id=1328 #include<stdio.h> #include<math.h> #define SIZE 100 double arr[SIZE][2]; typedef struct intersection{ double LP; double RP; }Inter; Inter data[SIZE]; //将岛屿按照坐标X排序(升序 void Change(int num){ int r1,r2; double tempx,tempy; for(r1=0;r1<num;r1++){ for(r2=r1+1;r2<num;r2++){ if(arr[r1][0]>arr[r2][0]){ tempx=arr[r1][0]; arr[r1][0]=arr[r2][0]; arr[r2][0]=tempx; tempy=arr[r1][1]; arr[r1][1]=arr[r2][1]; arr[r2][1]=tempy; } } } } //计算以(x,y)为圆心,雷达距离为半径所画的圆,与X轴的交点 void Cal(double x, double y, int radar, int p){ double temp=sqrt(pow(radar*1.0,2.0)-pow(y,2.0)); data[p].LP=x-temp; data[p].RP=x+temp; } //num是岛屿数,radar是雷达的覆盖范围 int Check(int num, int radar){ int RadarCount=0, r1=0; for(r1=0;r1<num;r1++){ Cal(arr[r1][0],arr[r1][1],radar,r1); } int r2; for(r1=0;r1<num;){ RadarCount++; //printf("%d\n",temp); for(r2=r1+1;r2<num;r2++){ //printf("r1:%d,r2:%d\n",r1,r2); if(data[r1].RP>data[r2].LP); else break; } r1=r2; } /* 检查计算岛屿与X轴交点的坐标是否正确 for(r1=0;r1<num;r1++) printf("%d:Left:%.3f\tRight:%.3f\n",r1,data[r1].LP,data[r1].RP); */ return RadarCount; } int main(void){ //n是岛屿数,d是雷达的覆盖距离 int n,d,r1,r2; int result[SIZE],resultcount=0,nothing=0; while(scanf("%d%d",&n,&d)==2 && n!=0 && d!=0){ nothing=0; for(r1=0;r1<n;r1++){ scanf("%lf%lf", &arr[r1][0], &arr[r1][1]); if(arr[r1][1]>d){ result[resultcount]=-1; nothing=-1; } } //puts("Get!"); if(nothing!=0) continue; //for(r1=0;r1<n;r1++) printf("%d %d\n",arr[r1][0],arr[r1][1]); //将岛屿按找X坐标排序 Change(n); //for(r1=0;r1<n;r1++) printf("%d %d\n",arr[r1][0],arr[r1][1]); result[resultcount]=Check(n,d); resultcount++; } for(r1=0;r1<resultcount;r1++) printf("case%d:%d\n",r1+1,result[r1]); return 0; }