初次接触贪心算法,之前上数据结构课曾经提到过,当时并不是学习重点(捂脸,渣渣表示老师说不考的就不是重点)。。废话不多说,然后刷oj1328,题目要求大致是在一片海洋中,有若干个岛,岛的地理位置为(x,y)型,y>0,然后装置若干个雷达,雷达的位置是在海平面上即y=0,问至少需要多少个岛。输入岛的个数和雷达的范围,之后依次输入岛屿的位置,输入一行空行后输出结果,类似Case x:x
以上就是题目背景,下面开始介绍这道题。。。
这个思维其实很常见,想要知道更多可以从最经典的背包问题去看啦。
运用到本题的话,思路大致如下:将若干个岛屿的位置放入数组中,然后根据每个岛屿,
因为岛屿位置与雷达范围均已知,是有两个雷达范围的,一个左边一个右边,
将这两个点位置范围加入到一个点对的集合(即元素是一对点数据)。因为只要雷达在这两点之间就可以扫描到该小岛。
所有的雷达范围均已确定,将其递增排序。之后就是贪心算法核心:
选择一个范围(start,end),将所有涉及到的范围去掉(即start小于等于前文范围的end)。
差不多就是这么多,遍历所有的范围即可。可能还是说的不太清楚,直接上代码:
#include <stdio.h>
#include <stdlib.h>
#include<math.h>
#include<string.h>
#define MAX 1005
struct{
int x,y;
}isI[MAX];
struct data{
float start,end;
}mm[MAX];
int cmp(const void *a,const void * b){
struct data * aa=(struct data*)a;
struct data * bb=(struct data*)b;
return aa->end>bb->end?1:-1;
}
int main()
{
int n,d;
int num=0;
while(scanf("%d",&n)==1&&scanf("%d",&d)==1&&n!=0){
int i,j,max_y=0;
for(i=0;i<n;i++){
scanf("%d",&isI[i].x);
scanf("%d",&isI[i].y);
if(isI[i].y>max_y)
max_y=isI[i].y;
}
getchar();
getchar();
printf("Case %d: ",++num);
if(max_y>d||d<0){
printf("-1\n");
continue;
}
float len;
for(i=0;i<n;i++){
len=sqrt(1.0*d*d-isI[i].y*isI[i].y);
mm[i].start=isI[i].x-len;
mm[i].end=isI[i].x+len;
}
qsort(mm,n,sizeof(mm[0]),cmp);
int ans=0;
int vis[MAX]={0};
memset(vis,0,sizeof(vis));
for(j=0;j<n;j++){
if(!vis[j]){
vis[j]=1;
for(i=0;i<n;i++)
if(!vis[i]&&mm[i].start<=mm[j].end)
vis[i]=1;
ans++;
}
}
printf("%d\n",ans);
}
return 0;
}
然后其实我也是参考其他大神http://cavenkaka.iteye.com/blog/1623400写的,我是用c写的,然后需要注意的问题就是qsort这个方法,bug了好久,注意其中的cmp算法是自定义的,格外注意对于不同的数据结构比较算法需要注意,int,char,double,以及struct是不同的哦!可以参考这篇文章:http://www.cnblogs.com/AndyJee/p/4676146.html