老鼠從洞 1 出發,速度 v,最多在洞外停留 m 分鐘。地面有 n 個洞(坐標)。老鼠能在兩洞間直線跑動,距離 ≤ v * m * 60 米則可到達。求能否從洞 1 到洞 2,能則輸出最少中轉洞數(不含起點終點)。
坐標輸入為浮點數(如 1.234)。為避免精度問題,放大 1000 倍轉整數:
int64 x = llround(input * 1000)。
距離平方比較:(dx*dx + dy*dy) <= (v * m * 60 * 1000)^2。
所有運算用 64 位整數,無浮點誤差。
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
struct Pt { ll x, y; };
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
ll v, m;
while (cin >> v >> m) {
ll maxd = v * m * 60 * 1000; // 放大 1000 後的最大距離
vector pts;
double x, y;
while (cin >> x >> y) {
pts.push_back({llround(x * 1000), llround(y * 1000)});
}
int n = pts.size();
vector> adj(n);
for (int i = 0; i < n; ++i) {
for (int j = i+1; j < n; ++j) {
ll dx = pts[i].x - pts[j].x;
ll dy = pts[i].y - pts[j].y;
if (dx*dx + dy*dy <= maxd*maxd) {
adj[i].push_back(j);
adj[j].push_back(i);
}
}
}
// BFS 求最短路(無權圖)
vector dist(n, -1);
queue q;
dist[0] = 0; q.push(0);
while (!q.empty()) {
int u = q.front(); q.pop();
for (int v : adj[u]) if (dist[v] == -1) {
dist[v] = dist[u] + 1;
q.push(v);
}
}
if (dist[1] == -1) cout << "No.\n";
else cout << "Yes, visiting " << dist[1] - 1 << " other holes.\n";
}
return 0;
}
這題是「幾何距離建圖 + BFS 最短路」的典型應用,整數放大技巧解決浮點精度問題,代碼清晰實用。