version 1
从右到左排序,每次都尽可能的选打击范围内最右边的点安装雷达(由于浮点,所以不要一棒子打死的判断是大是小,给出一个精度范围,一开始范围给打了就WA),拿这个雷达去覆盖其他点,最后雷达总数一定是最少的
/* poj 1328 264K 16MS */ #include<cstdio> #include<iostream> #include<algorithm> #include<cmath> #define MAXN 1005 using namespace std; struct node { double x,y,pos; node() { x = y = pos = -1.0; } }per[MAXN]; int n; double m; bool cmp(node a,node b) { return a.pos< b.pos; } bool init() { bool flag = true; for(int i = 1;i <= n;i ++) { scanf("%lf %lf",&per[i].x , &per[i].y); if(per[i].y > m) flag = false; per[i].pos = per[i].x + sqrt(m * m - per[i].y * per[i].y); } if(!flag) return false; sort(per + 1 , per + n + 1 , cmp); return true; } int calc() { int cnt = 0,id = 1; while(id <= n) { double now = per[id].pos; cnt ++; while(id <= n && (fabs(per[id].x - now) * (per[id].x - now) + per[id].y * per[id].y - m * m) <= 0.001) { id ++; } } return cnt ; } int main() { int cnt = 1; while(cin>>n>>m && (n || m)) { if(!init()) { printf("Case %d: -1\n",cnt); cnt ++; continue; } printf("Case %d: %d\n",cnt , calc()); cnt ++; } return 0; }
version 2
找到以每个岛为圆心的圆与x轴左右交点形成一个区间,按左端点关键字升序排序后,用右端点去覆盖之后的点(如果遇到更小的右端点应该把目前的点更新),遇到不能覆盖的就雷达数目+1
/* poj 1328 272K 32MS */ #include<cstdio> #include<cmath> #include<iostream> #include<algorithm> #define MAXN 1005 using namespace std; struct node { double x,y,lp,rp; node() { x = y = lp = rp = -1.0; } }per[MAXN]; int n; double m; bool cmp(node a,node b) { return a.lp < b.lp; } bool init() { bool flag = true; for(int i = 1;i <= n;i ++) { scanf("%lf %lf",&per[i].x , &per[i].y); if(per[i].y > m) flag = false; per[i].lp = per[i].x - sqrt(m * m - per[i].y * per[i].y); per[i].rp = per[i].x + sqrt(m * m - per[i].y * per[i].y); } if(!flag) return false; sort(per + 1 , per + n + 1 , cmp); return true; } int calc() { int cnt = 1,id = 1; bool mark[MAXN] = {false}; double now = per[1].rp; for(int i = 1;i <= n;i ++) { if(per[i].rp < now) now = per[i].rp; if(per[i].lp > now) { cnt ++; now = per[i].rp; } } return cnt; } int main() { int cnt = 1; while(cin>>n>>m && (n || m)) { if(!init()) { printf("Case %d: -1\n",cnt); cnt ++; continue; } printf("Case %d: %d\n",cnt , calc()); cnt ++; } return 0; }
原文地址:http://blog.csdn.net/poloyzhang/article/details/26577007