zoj1360贪心

来源:互联网 发布:lol for mac国服 编辑:程序博客网 时间:2024/06/06 12:36
//题意理解:以x轴为海岸线,x轴以上为海域,以下为大陆,海上有若干岛屿//在海岸线上放置雷达,雷达的覆盖半径为d,求覆盖所有岛屿所需雷达的最小数量//  以每一个岛屿为圆心,d为半径画圆交x轴与两点x1,x2。得到区间【x1,x2】//将区间以左端值大小从小到大排序,从左到右扫描//如果多个区间有公共区,则雷达放在公共区,便能覆盖产生这些区间的岛屿#include"stdio.h"#include"stdlib.h"#include"math.h"#define max 1002typedef struct A{int x,y;}node;//岛屿坐标数据结构typedef struct B{double l,r;}interval;//区间数据结构int n,d;node nodes[1002];interval intervals[1002];int getinterval(int a,int b,int j);//以岛屿坐标为圆心,d为半径的圆与横轴的交点作为区间的左右端点int doit();//贪心求解,int cmp(const void *a,const void *b);int main(){FILE*fp=fopen("D:input1.txt","r");int i,kegao,ct=0;fscanf(fp,"%d%d",&n,&d);while(d&&n){kegao=1;for(i=0;i<n;i++){fscanf(fp,"%d%d",&nodes[i].x,&nodes[i].y);if(nodes[i].y>d)//不能覆盖的情况{kegao=0;break;}}if(kegao){for(i=0;i<n;i++)getinterval(nodes[i].x,nodes[i].y,i);qsort(intervals,n,sizeof(interval),cmp);//将区间以左端值大小从小到大排序printf("Case %d: %d\n",++ct,doit());}elseprintf("Case %d: -1\n",++ct);fscanf(fp,"%d%d",&n,&d);}return 0;}int getinterval(int a,int b,int j){double d0,b0,temp;d0=(double)d;b0=(double)b;temp=sqrt(d0*d0-b0*b0);intervals[j].l=a-temp;intervals[j].r=a+temp;return 0;}int doit(){int i,count=0;double right = intervals[0].r;//从左端点最小的区间开始,for(i = 1;i < n;i++){if(right >=intervals[i].l)//如果下一个区间的左端点大于当前区间的右端点则这两个区间有公共区,则公用一台雷达{if(right>=intervals[i].r)right =intervals[i].r>right?right:intervals[i].r;//将right更改为公共区间的右端点}else//如果无公共区间,需增加雷达数量{count++;right = intervals[i].r;}}return ++count;}int cmp(const void *a,const void *b){interval  *a0,*b0;a0=(interval*)a;b0=(interval*)b;if(((a0)->l>(b0)->l))return 1;if(((a0)->l<(b0)->l))return -1;else return 0;}

原创粉丝点击