POJ 1328 Radar Installation 貪心題解
本題是貪心法題解。只是須要自己觀察出規律。這就不easy了,非常easy出錯。
一般網上做法是找區間的方法。
這裏給出一個獨特的方法:
1 依照x軸大小排序
2 從最左邊的點循環。首先找到最小x軸的圓
3 以這個圓推斷能夠包含右邊的多少個圓,直到不能夠包含下一個點,那麽繼續第2步,畫一個新圓。
看代碼吧,應該非常清晰直觀的了。
效率是O(n),盡管有嵌套循環。可是下標沒有反復。一遍循環就能夠了。故此是O(n)。
#include <stdio.h> #include <cmath> #include <algorithm> #include <float.h> using namespace std; const int MAX_N = 1001; inline float MAX(float a, float b) { return a > b ?a : b; } inline float MIN(float a, float b) { return a < b ?
a : b; } struct Point { float x, y; bool operator<(const Point &p) const { if (x == p.x) return y > p.y; return x < p.x; } float dist(const Point &p) const { float a = (x - p.x); float b = (y - p.y); return sqrtf(a*a+b*b); } float dist(const float x1, const float y1) const { float a = (x - x1); float b = (y - y1); return sqrtf(a*a+b*b); } }; Point ps[MAX_N]; int calRadar(int n, int d) { sort(ps, ps+n); float cenX = 0.0f, cenY = 0.0f; int ans = 0; for (int i = 0; i < n; ) //視情況而添加i { ans++; float dx = sqrtf(float(d*d) - ps[i].y*ps[i].y); cenX = ps[i].x + dx; for (i++; i < n && ps[i].x <= cenX; i++) { dx = sqrtf(float(d*d) - ps[i].y*ps[i].y); cenX = MIN(cenX, ps[i].x + dx); } float dis = 0.0f; for ( ; i < n; i++) { dis = ps[i].dist(cenX, cenY); if (dis > float(d)) break; } } return ans; } int main() { int n, d, t = 1; while (scanf("%d %d", &n, &d) && (n || d)) { float maxY = FLT_MIN;//這個放外面了,錯誤!
for (int i = 0; i < n; i++) { scanf("%f %f", &ps[i].x, &ps[i].y); maxY = MAX(ps[i].y, maxY); } if (maxY > (float)d) printf("Case %d: -1\n", t++); else printf("Case %d: %d\n", t++, calRadar(n, d)); } return 0; }
POJ 1328 Radar Installation 貪心題解