解题思路
使用动态规划计算概率:
- 使用while(cin)持续读入数据
- 从终点反向计算到起点的概率
- 处理蘑菇和边界情况
关键点
- 持续读入数据直到EOF
- 每组数据独立处理
- 保持精度要求
代码
#include <iostream>
#include <vector>
#include <iomanip>
using namespace std;
class Solution {
public:
double safePath(int n, int m, vector<pair<int,int>>& mushrooms) {
vector<vector<bool>> hasMushroom(n + 1, vector<bool>(m + 1, false));
for (const auto& pos : mushrooms) {
hasMushroom[pos.first][pos.second] = true;
}
if (hasMushroom[n][m]) return 0.0;
vector<vector<double>> dp(n + 1, vector<double>(m + 1, 0.0));
dp[n][m] = 1.0;
for (int i = n; i >= 1; i--) {
for (int j = m; j >= 1; j--) {
if ((i == n && j == m) || hasMushroom[i][j]) continue;
int moves = 0;
double prob = 0.0;
if (j < m) {
moves++;
prob += dp[i][j + 1];
}
if (i < n) {
moves++;
prob += dp[i + 1][j];
}
if (moves > 0) {
dp[i][j] = prob / moves;
}
}
}
return dp[1][1];
}
};
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout << fixed << setprecision(2);
int n, m, k;
while (cin >> n >> m >> k) {
vector<pair<int,int>> mushrooms;
for (int i = 0; i < k; i++) {
int x, y;
cin >> x >> y;
mushrooms.emplace_back(x, y);
}
Solution solution;
cout << solution.safePath(n, m, mushrooms) << endl;
}
return 0;
}
import java.util.*;
public class Main {
static class Solution {
public double safePath(int n, int m, int[][] mushrooms) {
boolean[][] hasMushroom = new boolean[n + 1][m + 1];
for (int[] pos : mushrooms) {
hasMushroom[pos[0]][pos[1]] = true;
}
if (hasMushroom[n][m]) return 0.0;
double[][] dp = new double[n + 1][m + 1];
dp[n][m] = 1.0;
for (int i = n; i >= 1; i--) {
for (int j = m; j >= 1; j--) {
if ((i == n && j == m) || hasMushroom[i][j]) continue;
int moves = 0;
double prob = 0.0;
if (j < m) {
moves++;
prob += dp[i][j + 1];
}
if (i < n) {
moves++;
prob += dp[i + 1][j];
}
if (moves > 0) {
dp[i][j] = prob / moves;
}
}
}
return dp[1][1];
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (sc.hasNext()) {
int n = sc.nextInt();
int m = sc.nextInt();
int k = sc.nextInt();
int[][] mushrooms = new int[k][2];
for (int i = 0; i < k; i++) {
mushrooms[i][0] = sc.nextInt();
mushrooms[i][1] = sc.nextInt();
}
Solution solution = new Solution();
System.out.printf("%.2f%n", solution.safePath(n, m, mushrooms));
}
sc.close();
}
}
def safe_path(n, m, mushrooms):
has_mushroom = [[False] * (m + 1) for _ in range(n + 1)]
for x, y in mushrooms:
has_mushroom[x][y] = True
if has_mushroom[n][m]:
return 0.0
dp = [[0.0] * (m + 1) for _ in range(n + 1)]
dp[n][m] = 1.0
for i in range(n, 0, -1):
for j in range(m, 0, -1):
if (i == n and j == m) or has_mushroom[i][j]:
continue
moves = 0
prob = 0.0
if j < m:
moves += 1
prob += dp[i][j + 1]
if i < n:
moves += 1
prob += dp[i + 1][j]
if moves > 0:
dp[i][j] = prob / moves
return dp[1][1]
def main():
while True:
try:
n, m, k = map(int, input().split())
mushrooms = []
for _ in range(k):
x, y = map(int, input().split())
mushrooms.append((x, y))
result = safe_path(n, m, mushrooms)
print(f"{result:.2f}")
except EOFError:
break
if __name__ == "__main__":
main()
算法及复杂度
- 算法:动态规划
- 时间复杂度:,每组数据需要遍历整个网格
- 空间复杂度:,需要dp数组存储概率