Radar Installation(POJ1328, 贪心)

来源:互联网 发布:oracle数据库日志位置 编辑:程序博客网 时间:2024/06/16 01:22

题目链接

       这个题的解题思路是这样的:

       if (y > d)     输出-1就行了

       else

       1.计算区间(端点为x ± sqrt(d*d - y*y),表示在这个区间上建雷达能够覆盖到该岛)

       2.排序

       无论是按左端点升序还是右端点升序排还是按坐标x升序排(按x排的话要排完序再计算区间,具体可看代码)都行,不过后续具体处理会不一样,但思路一样

       3.遍历区间

       对于第一个区间(即第一个岛),必定要有一个雷达用来覆盖这个岛,运用贪心的思想,那么与此同时能够覆盖更多的其它岛最好,遍历区间直到那个无法被同时覆盖的区间,ans++。(这里要解释一下,在那个无法被同时覆盖的区间后面可能依然存在能够被被第一个雷达覆盖到的岛,但我们没有对它进行任何处理,这是因为这个岛一定能够被前面说的“那个无法被同时覆盖的区间”所表示的岛的雷达覆盖到,这一点大家可以想一下,这里不展开解释了)

        *在贴出代码之前我想问一个问题,浮点数的误差问题在这里不会影响结果吗?如果有知道的童鞋,麻烦评论一下,感激不尽。

        下面贴出以三种方式排序的代码

         按坐标x升序排

#include<cstdio>#include<algorithm>#include<cmath>using namespace std;const int MAX_n = 1005;struct island {double begin;double end;} a[MAX_n];typedef struct island Island;int n, d, cnt = 1, ans = 1;bool cmp(Island b, Island c){return b.begin<c.begin;}void get_interval(){for(int i=0; i<n; i++){int y = a[i].end;a[i].end = a[i].begin + sqrt(d*d - y*y);a[i].begin = a[i].begin - sqrt(d*d - y*y); //printf("%f %f\n", a[i].begin, a[i].end);} }void greedy(){double now = a[0].end;for(int i=1; i<n; i++){if(a[i].begin > now){ans++;now = a[i].end;}else if(a[i].end<now) now = a[i].end; }}int main(){while(~scanf("%d%d", &n, &d) && (n!=0 || d!=0)){ ans = 1;int flag = 1;for(int i=0; i<n; i++){scanf("%lf%lf", &a[i].begin, &a[i].end);//先临时保存下坐标,一会用此坐标计算区间 if(a[i].end > d) flag = 0;}if(flag){sort(a, a+n, cmp);get_interval();greedy();printf("Case %d: %d\n", cnt, ans);} else printf("Case %d: -1\n", cnt);cnt++;}return 0;} 

        按左端点升序

#include<cstdio>#include<algorithm>#include<cmath>using namespace std;const int MAX_n = 1005;struct island {double begin;double end;} a[MAX_n];typedef struct island Island;int n, d, cnt = 1, ans = 1;bool cmp(Island b, Island c){return b.begin<c.begin;}void greedy(){double now = a[0].end;for(int i=1; i<n; i++){if(a[i].end < now){now = a[i].end;}else if(a[i].begin > now){ans++;now = a[i].end;}}}int main(){while(~scanf("%d%d", &n, &d) && (n!=0 || d!=0)){ ans = 1;int flag = 1;for(int i=0; i<n; i++){int x, y; scanf("%d%d", &x, &y);if(y > d) flag = 0;if(flag){a[i].begin = x - sqrt(d*d - y*y);a[i].end = x + sqrt(d*d - y*y);}}if(flag){sort(a, a+n, cmp);greedy();printf("Case %d: %d\n", cnt, ans);} else printf("Case %d: -1\n", cnt);cnt++;}return 0;} 

        右端点升序排

#include<cstdio>#include<algorithm>#include<cmath>using namespace std;const int MAX_n = 1005;struct island {double begin;double end;} a[MAX_n];typedef struct island Island;int n, d, cnt = 1, ans = 1;bool cmp(Island b, Island c){return b.end<c.end;}void greedy(){/*int now = a[0].end;for(int i=1; i<n; i++){if(a[i].end < now){now = a[i].end;}else if(a[i].begin > now){ans++;now = a[i].end;}}*/double now = a[0].end;for(int i=1;i<n;i++)if(a[i].begin>now){now=a[i].end;        ans++;}}int main(){while(~scanf("%d%d", &n, &d) && (n!=0 || d!=0)){ ans = 1;int flag = 1;for(int i=0; i<n; i++){int x, y; scanf("%d%d", &x, &y);if(y > d) flag = 0;if(flag){a[i].begin = x - sqrt(d*d - y*y);a[i].end = x + sqrt(d*d - y*y);}}if(flag){sort(a, a+n, cmp);greedy();printf("Case %d: %d\n", cnt, ans);} else printf("Case %d: -1\n", cnt);cnt++;}return 0;} 


原创粉丝点击