題目在此數組
解題思路:性能
以島嶼座標爲圓心,輸入值爲半徑畫圓,此圓會與 X 軸相交於 S、E 兩點(島嶼 Y 座標等於圓半徑時,交一點;Y 座標大於圓半徑的狀況提早排除,不參與後面的計算)。而後對由 S、E 組成的線段以 E 爲斷定標準排序,從左至右計算最少雷達個數。優化
吐個槽:POJ 落後於時代了,支持語言少,不支持 C++11 也就罷了,大多數題目時限居然只有 1000ms。這道題我一開始是用 vector、cin/cout 等 C++ 經常使用特性作的,提交後居然超時。無奈用 C 重寫——改用 scanf/printf、靜態建立數組等等。邏輯沒變,再次提交,運行時間減爲 16ms(這種狀況已是第二次碰到了,看來之後寫 POJ 程序時得專門針對題目優化才行了)。讓你們重視程序運行性能當然沒錯,但相信真正寫程序的話沒人會以靜態建立數組的方法把數據的處理規模寫死吧?咱們不能爲了作題而作題,對吧?code
不囉嗦了,上代碼。對象
#include <cstdio> #include <algorithm> #include <cmath> // 島嶼對象 struct coordinate { // 座標、與 X 軸相交線段的起/終點 double x, y; double s, e; bool operator<(const coordinate &o) const { return e < o.e; } } island[1001]; int solve(int n, int d) { // 計算相交線段起/終點 for (int i = 0; i < n; ++i) { double t = sqrt(d - island[i].y * island[i].y); island[i].s = island[i].x - t; island[i].e = island[i].x + t; } // 依線段終點排序 std::sort(island, island + n); // 最少雷達數量(特殊狀況已在輸入時排除掉, // 程序執行到這裏時,至少存在一個合法島嶼, // 故 ans 初始爲 1) int ans = 1; double r = island[0].e; // 從第二座島嶼開始掃描,如前一雷達設置點 // 覆蓋不到,則雷達數加 1 for (int i = 1; i < n; ++i) { if (island[i].s > r) { ++ans; r = island[i].e; } } return ans; } int main() { int c = 1; int n, d; while (scanf("%d %d", &n, &d) && (n || d)) { bool np = false; for (int i = 0; i < n; ++i) { // 座標明明爲整數,但用 scanf 時 // 後面計算時會出現精度不夠的狀況, // 用 cin 則無此問題 -_-!!! scanf("%lf %lf", &island[i].x, &island[i].y); // 若是島嶼座標超出雷達覆蓋範圍, // 排除此狀況,不參與計算 if (island[i].y > d) { np = true; } } if (np) { printf("Case %d: %d\n", c, -1); } else { // 直接傳入半徑平方,減小重複計算 printf("Case %d: %d\n", c, solve(n, d * d)); } ++c; } return 0; }