貌似这么久了我还是在走水题这条路,很多伤感,好好考虑一下。
昨天晚上整了个贪心的题目来看下,不过貌似还是水题,可能是自己能力太有限了吧,不敢做有水平的题目,怕自己的信心受太大的打击,就总是徘徊于这些water之间,真的要好好想想。
就这个题目而言,有可能会走误区,就是从左开始先选一个点然后让它右移覆盖尽可能多的点,但这样是错误的,例如给出n=2,d=3,然后给出点0,2和 2,3,如果按这种思路是得到的结果就是,但事实上一个就可以做到了。开始想到也是这样的,后面还有过一些杂七杂八的想法,结果都被否定了,最后想到的是 这种以island为圆心作圆的办法,今变量pre为前一个圆所能表示的最右边的坐标,然后用贪心的思想从左到右遍历并不断更新就好了。
#include <iostream> #include <cmath> #include <algorithm> using namespace std; int n, d; typedef struct { double left, right; }Point; Point islands[1000]; bool compare(Point a, Point b) { return (a.left-b.left) < 10e-7; } int greedy() { //贪心法计算最小需要的radar数 int ans = 1; double pre = islands[0].right; //前一radar的位置 for(int i = 1; i < n; i++) { if(islands[i].left-pre > 10e-7) { ans++; pre = islands[i].right; } else { if(islands[i].right-pre < 10e-7) pre = islands[i].right; } } return ans; } int main() { int cas = 0, x, y; while(scanf("%d%d", &n, &d) != EOF) { if(!n && !d) break; bool impossible = false; for(int i = 0; i < n; i++) { scanf("%d%d", &x, &y); if(!impossible && (y <= d)) { double tmp = sqrt(double(d*d-y*y)); islands[i].left = x-tmp; islands[i].right = x+tmp; } else impossible = true; } if(impossible) { printf("Case %d: -1\n", ++cas); continue; } sort(islands, islands+n, compare);//将island按左端点left由小到大排序 printf("Case %d: %d\n", ++cas,greedy()); } return 0; }