本题的题意为:在x轴上有地雷,有一个半径为d的范围,现在岛位于x轴上或上方,(注意可能在x轴上),现要求求出能将所有岛包含的地雷的最小个数。
那么这题,我们可以模拟成这样的问题:有一系列的点,要你画圆,将所有这些点包含,最少的园的个数。通常我们会从左到右的画圆,每个园包含数量最多的点,直到不行为止,这时画另一个园,一直这样下去,就可以求出最小的数量了。那么这就是符合贪心的条件了:局部最优解,具体到本题就对应于一个园所能包含的最大的点数。理解了这点就不难解决这题了。
下面是代码:
//#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <cmath>
//using namespace std;
#define Max 1000
#define maxn(a,b) (a)>(b)?(a):(b)
#define minn(a,b) (a)<(b)?(a):(b)
struct Por
{
int x;
int y;
}node[Max];
int n,d,ans;
inline double L_limit(int ,int );
inline double R_limit(int ,int );
int cmp(const void*,const void*);
int main()
{
int time=1;
while(scanf("%d%d",&n,&d),n)
{
int i;
bool trag=true;
for(i=0;i<n;i++){
scanf("%d%d",&node[i].x,&node[i].y);
if(node[i].y<0 || node[i].y>d)
trag=false;
}
if(!trag || d<=0)
printf("Case %d: -1\n",time++);
else
{
qsort(node,n,sizeof(Por),cmp);
double left=L_limit(node[0].x,node[0].y);
double right=R_limit(node[0].x,node[0].y);
ans=1;
for(i=1;i<n;i++){
double xL=L_limit(node[i].x,node[i].y);
double xR=R_limit(node[i].x,node[i].y);
if(xL<=right){
left=maxn(xL,left);
right=minn(xR,right);
}
else{
ans++;
left=xL;
right=xR;
}
}
printf("Case %d: %d\n",time++,ans);
}
}
return 0;
}
inline double L_limit(int x,int y){
return x-sqrt(double(d*d-y*y));
}
inline double R_limit(int x,int y){
return x+sqrt(double(d*d-y*y));
}
int cmp(const void*p,const void*q){
if(((Por *)p)->x!=((Por *)q)->x)
return ((Por *)p)->x-((Por *)q)->x;
else
return ((Por *)p)->y-((Por *)q)->y;
其实这题是模拟与贪心的结合,另外注意d<=0时的情况,还有点在坐标上的情况。
下面是测试数据:
希望对大家有用。2 5 -3 4 -6 3 4 5 -5 3 -3 5 2 3 3 3 20 8 -20 7 -18 6 -5 8 -21 8 -15 7 -17 5 -1 5 -2 3 -9 6 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 7 9 6 10 5 0 0 2 3 0 2 2 3 2 3 0 2 1 3 3 3 1 2 -3 2 2 4 8 5 2 4 -4 4 -3 3 -3 1 -3 0 -1 0 0 5 6 0 3 0 1 2 -3 1 2 1 3 2 1 2 -3 1 2 1 1 2 0 2 2 3 0 2 2 3 4 -5 4 3 4 3 2 3 6 -9 3 -3 1 2 -3 2 2 1 6 2 1 2 1 2 1 2 -3 1 2 1 0 0 1 2 0 2 2 3 0 2 1 3 3 10 1 10 2 3 4 5 3 5 1 10 2 3 4 5 4 7 1 10 2 3 4 5 0 0 3 9 1 10 2 3 4 5 0 0 ================结果 Case 1: 1 Case 2: 2 Case 3: 4 Case 4: 1 Case 5: 1 Case 6: -1 Case 7: 3 Case 8: -1 Case 9: 2 Case 10: 1 Case 11: 1 Case 12: -1 Case 13: -1 Case 14: 2 Case 15: 1 Case 16: 1 Case 17: 1 Case 18: -1 Case 19: -1 Case 20: -1