输入包含多组数据。对于每组数据,第一行为草地大小。
接下来行,每行两个整数
,代表
处有一个蘑菇。
对于每组数据,输出一行,代表所求概率(保留到2位小数)
2 2 1 2 1 6 16 2 1 10 1 13
0.50 1.00
//动态规划的思想
import java.util.*;
public class Main{
public static double dp(int[][] arr,int n,int m){
double[][] res = new double[n+1][m+1];
res[1][1] = 1.0;
for(int i = 1;i <= n;i++){
for(int j = 1;j <= m;j++){
//如果A不在(1,1)位置,此时他有两个方向可以走(向左或者向右),概率均为0.5
//在最后一列和最后一行的时候他只有一个方向可以走,所以概率为1.0 if(!(i == 1 && j == 1)){
res[i][j] = res[i - 1][j] * (j == m ? 1.0 : 0.5) + res[i][j - 1] * (i == n ? 1.0 : 0.5);
}
//如果arr[i][j]位置是蘑菇,则不可能走到该位置,所以该位置的概率为0.0
if(arr[i][j] == 1){
res[i][j] = 0.0;
}
}
}
return res[n][m];
}
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
while(sc.hasNext()){
int n = sc.nextInt();
int m = sc.nextInt();
int[][] arr = new int[n+1][m+1];
int k = sc.nextInt();
while(k != 0){
int x = sc.nextInt();
int y = sc.nextInt();
arr[x][y] = 1;
k--;
}
double result = dp(arr,n,m);
System.out.printf("%.2f\n",result);
}
}
}
#include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
using namespace std;
int main()
{ int N,M,K,x,y; double dp[25][25]; bool has[25][25]; while(cin>>N>>M>>K) { memset(dp,0,sizeof(dp)); memset(has,false,sizeof(has)); for(int i=0;i<K;i++) { cin>>x>>y; has[x][y] = true; } for(int i=1;i<=N;i++) for(int j=1;j<=M;j++) { if(i==1 && j==1) { dp[i][j] = 1; continue; } if(has[i][j]) { dp[i][j] = 0; continue; } if(i==N && j==M) { dp[i][j] = dp[i-1][j] + dp[i][j-1]; continue; } if(i==N) { dp[i][j] = dp[i-1][j]*0.5 + dp[i][j-1]; continue; } if(j==M) { dp[i][j] = dp[i-1][j] + dp[i][j-1]*0.5; continue; } if(i==1) { dp[i][j] = dp[i][j-1]*0.5; continue; } if(j==1) { dp[i][j] = dp[i-1][j]*0.5; continue; } dp[i][j] = dp[i-1][j]*0.5 + dp[i][j-1]*0.5; } printf("%.2f\n", dp[N][M]); }
return 0;
}
//可行路径/总路径的方法不对,讨论里说道用概率求。
#include<iostream>
#include<vector>
using namespace std;
int main(){
int N, M, K;
while(cin>>N>>M>>K){
vector<vector<float>> input(N+1, vector<float>(M+1, 0));
int x, y;
for(int i = 0; i < K; ++i){
cin>>x>>y;
input[x][y] = -1; //-1表示有蘑菇
}
for(int i = 1; i <= N; ++i){
for(int j = 1; j <= M; ++j){
if(i==1 && j == 1) input[1][1] = 1;
else if(input[i][j] != -1){
if(i != N && j != M)
input[i][j] = input[i-1][j]*0.5 + input[i][j-1]*0.5;
if(i == N && j != M)
input[i][j] = input[i-1][j]*0.5 + input[i][j-1];
if(i != N && j == M)
input[i][j] = input[i-1][j] + input[i][j-1]*0.5;
if(i == N && j == M)
input[i][j] = input[i-1][j] + input[i][j-1];
}
else input[i][j] = 0;
}
}
printf("%.2f\n", input[N][M]);
}
return 0;
}
#include <iostream>
#include <cstring>
using namespace std;
int map[26][26];
double dp[26][26];
int N, M, K;
void init()
{
memset(map, 0, sizeof(map));
for(int i = 0; i <= N; i++)
for(int j = 0; j <= M; j++)
dp[i][j] = 0;
}
int judge(int x, int y)
{
return x <= N && x >= 1 && y <= M && y >= 1;
}
int main()
{
while(scanf("%d%d%d", &N, &M, &K) != EOF)
{
init();
for(int i = 0; i < K; i++)
{
int x;
int y;
scanf("%d%d", &x, &y);
map[x][y] = 1;
}
dp[1][1] = 1;
for(int i = 1; i <= N; i++)
{
for(int j = 1; j <= M; j++)
{
if(map[i][j] == 1)
dp[i][j] = 0;
if(judge(i + 1, j) && judge(i, j + 1))
{
dp[i + 1][j] += dp[i][j] * 0.5;
dp[i][j + 1] += dp[i][j] * 0.5;
}
else if(judge(i + 1, j))
dp[i + 1][j] += dp[i][j];
else if(judge(i, j + 1))
dp[i][j + 1] += dp[i][j];
}
}
printf("%.2lf\n", dp[N][M]);
}
return 0;
}
/*
1 0.5 0.25
0.5 0 0.25
0 0 0.25
1 0.5
0.5 1
*/
}
//运行通过
#include<iostream>
#include<iomanip>
using namespace std;
int main()
{
int row, column, block;
while (cin >> row >> column >> block)
{
if (block == 0)
cout << setiosflags(ios::fixed) << setprecision(2) << 1.00 << endl;
else{
int * xptr = new int[block];
int * yptr = new int[block];
for (int i = 0; i < block; ++i)
cin >> xptr[i] >> yptr[i];
double ** iArray = new double*[row + 1];
for (int i = 0; i <= row; ++i)
iArray[i] = new double[column + 1];
for (int i = 0; i <= row; ++i)
iArray[i][0] = 0.0;
for (int j = 0; j <= column; ++j)
iArray[0][j] = 0.0;
iArray[1][0] = 2.0;
for (int i = 1; i <= row; ++i)
for (int j = 1; j <= column; ++j)
iArray[i][j] = 1.0;
for (int i = 0; i < block; ++i)
iArray[xptr[i]][yptr[i]] = 0.0;
for (int i = 1; i <= row; ++i)
for (int j = 1; j <= column; ++j)
if (iArray[i][j] == 0.0)
continue;
else
iArray[i][j] = (i == row ? iArray[i][j - 1] : 0.5*iArray[i][j - 1])
+ (j == column ? iArray[i - 1][j] : 0.5*iArray[i - 1][j]);
cout << setiosflags(ios::fixed) << setprecision(2) << iArray[row][column] << endl;
for (int i = 0; i <= row; ++i)
delete[]iArray[i];
delete[]iArray;
delete[]xptr;
delete[]yptr;
}
}
return 0;
}
#include <stdlib.h>#include <stdio.h>#include <math.h>//不能用可走路径数/总路径数进行计算//在下边界时,只能向右走,不能向下走,向右概率为1,右边界同理//而在非边界时,向下和向右的概率分别为0.5//我也是在看了Bestmouse皓的java代码意识到的, thsint main(){int n, m;int cn, cm, k;double **b;int i,j;while(~scanf("%d %d %d", &n, &m, &k)){b=new double*[n]();for(i=0; i<n; i++){b[i]=new double[m]();for(j=0; j<m; j++)b[i][j]=1.0;}for(i=0; i<k; i++){scanf("%d %d", &cn, &cm);b[cn-1][cm-1]=0.0;}for(i=1; i<n; i++){if(b[i][0]==0||b[i-1][0]==0)b[i][0]=0;else if(m>1) b[i][0]=0.5*b[i-1][0];}for(j=1; j<m; j++){if(b[0][j]==0||b[0][j-1]==0)b[0][j]=0;else if(n>1) b[0][j]=0.5*b[0][j-1];}for(i=1; i<n; i++){for(j=1; j<m; j++){if(b[i][j]==0.0) continue;else b[i][j]=(j==m-1?1:0.5)*b[i-1][j]+(i==n-1?1:0.5)*b[i][j-1];}}printf("%0.2f\n", b[n-1][m-1]);for(i=0; i<n; i++){delete [] b[i];}delete [] b;}}
#include <iostream>
#include <iomanip>
#include <vector>
#include <algorithm>
using namespace std;
//到最后一行,向右走的概率为1。同理在最后一列时候,向下走概率也为1。
//其它的都是用 fn[i][j] = 0.5*fn[i][j-1] + 0.5*fn[i-1][j];
int main()
{
int n,m,k;
while (cin>>n>>m>>k)
{
vector<vector<int>> mp(n+1, vector<int>(m+1, 0));
vector<vector<float>> fn(n+1, vector<float>(m+1, 0));
for (int i = 0; i < k; i++)
{
int x,y;
cin>>x>>y;
mp[x][y] = 1;
}
fn[1][1] = 1.0;
for (int i = 1; i <= n; i++){
for (int j = 1; j <= m; j++){
if(i==1 && j==1)
continue;
if(mp[i][j]==1)
fn[i][j] = 0.0;
else
fn[i][j] = (i==n?1:0.5)*fn[i][j-1] + (j==m?1:0.5)*fn[i-1][j];
}
}
float ans = fn[n][m];
cout.setf(ios::fixed);
cout<<setprecision(2)<<ans<<endl;
}
return 0;
}
#include <iostream>
#include <vector>
#include <iomanip>
using namespace std;
int main()
{
int n, m, k, i, j, x, y;
vector<int> a;
vector<float> p;
vector<vector<int>> b;
vector<vector<float>> q;
while (cin >> n >> m >> k) {
for (i = 0; i < n; ++i) {
for (j = 0; j < m; ++j) { a.push_back(0); p.push_back(0.0); }
b.push_back(a); q.push_back(p); a.clear(); p.clear();
}
for (i = 0; i < k; i++) { cin >> x >> y; b[x - 1][y - 1] = 1; }
//--以上都是准备工作-----------------------------------------------------
if (n == 1 || m == 1) { float ans = k == 0 ? 1 : 0; cout << fixed << setprecision(2) << ans << endl; }
else {
for (i = 0; i < n; ++i) {
for (j = 0; j < m; ++j) {
if (i == 0 && j == 0) { q[0][0] = 1.0; }
else if (i == 0) { q[i][j] = b[i][j] == 0 ? q[i][j - 1] * 0.5 : 0; }
else if (j == 0) { q[i][j] = b[i][j] == 0 ? q[i - 1][j] * 0.5 : 0; }
else if (i == n - 1 && j > 0 && j < m - 1) { q[i][j] = b[i][j] == 0 ? q[i][j - 1] * 1 + q[i - 1][j] * 0.5 : 0; }
else if (j == m - 1 && i > 0 && i < n - 1) { q[i][j] = b[i][j] == 0 ? q[i][j - 1] * 0.5 + q[i - 1][j] * 1 : 0; }
else if (i == n - 1 && j == m - 1) { q[i][j] = b[i][j] == 0 ? q[i][j - 1] * 1 + q[i - 1][j] * 1 : 0; }
else { q[i][j] = b[i][j] == 0 ? q[i][j - 1] * 0.5 + q[i - 1][j] * 0.5 : 0; }
}
}
cout << fixed << setprecision(2) << q[i - 1][j - 1] << endl;
b.clear();
q.clear();
}
}
return 0;
}
递归一下,就没了。#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
using namespace std;
bool maze[23][23];
double p[23][23];
int main(){
int n,m,k;
while(~scanf("%d%d%d",&n,&m,&k)){
int x,y;
memset(maze,false,sizeof maze);
for(int i = 0;i<k;i++){
scanf("%d%d",&x,&y);
maze[x][y] = true;
}
memset(p,0,sizeof p);
p[1][1] = 1;
for(int i = 1;i<=n;i++)
for(int j = 1;j<=m;j++){
if( maze[i][j])
continue;
double tmp = ((i == n || j == m ) ? 1 : 0.5 ) * p[i][j];
p[i+1][j] += tmp;
p[i][j+1] += tmp;
}
printf("%.2lf\n",p[n][m]);
}
}
//要使用动态规划,注意每个点的概率来源,第一行的点,如(1,3)的概率来源只有它左边点(1,2)的1/2,
//第n行的点如(n,3),概率来源为(n,2)+(n-1,3)*1/2,因为(n,2)只能往右走,概率为1。其他的特征点在程序段中列出
#include <iostream>
#include <iomanip>
#include<cstring>
using namespace std;
int has[25][25];//有无蘑菇
double dp[25][25];//能够到达每个格子的概率
int main(){
int n, m, k;
while(cin >> n >> m >> k){
int i, j;
memset(has, 0, sizeof(has));
memset(dp, 0, sizeof(dp));
int x, y;
for(i = 0; i < k; ++i){
cin >> x >> y;
has[x][y] = 1;
}
for(i = 1; i <= n; ++i){
for(j = 1; j <= m; ++j){
if(i == 1 && j == 1) {dp[1][1] = 1; continue;}
if(has[i][j]) {dp[i][j] = 0; continue;}
if(i == n && j == m) {dp[i][j] = dp[i-1][j] + dp[i][j-1]; continue;}
if(i == n) {dp[i][j] = dp[i-1][j]*0.5 + dp[i][j-1]; continue;}
if(j == m) {dp[i][j] = dp[i-1][j] + dp[i][j-1]*0.5; continue;}
if(i == 1) {dp[i][j] = dp[i][j-1]*0.5; continue;}
if(j == 1) {dp[i][j] = dp[i-1][j]*0.5; continue;}
dp[i][j] = dp[i][j-1]*0.5 + dp[i-1][j]*0.5;
}
}
cout << fixed << setprecision(2) << dp[n][m] << endl;
}
return 0;
}
//直接用概率进行DP,用路径数是不对的
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner sca = new Scanner(System.in);
while(sca.hasNext()){
int n = sca.nextInt();
int m = sca.nextInt();
int k = sca.nextInt();
boolean[][] map = new boolean[n][m];
for(int i = 0; i < k; i++) {
int x = sca.nextInt()-1;
int y = sca.nextInt()-1;
map[x][y] = true;
}
double[][] cw = new double[n][m];
cw[0][0] = 1;
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
if(map[i][j]) cw[i][j] = 0;
else if(i == 0 && j == 0) {}
else cw[i][j] = (j-1<0?0:(i+1<n?cw[i][j-1]*0.5:cw[i][j-1]))+(i-1<0?0:(j+1<m?cw[i-1][j]*0.5:cw[i-1][j]));
//System.out.print(String.format("%.5f",cw[i][j])+" ");
}
//System.out.println();
}
double res = cw[n-1][m-1];
System.out.println(String.format("%.2f", res));
}
}
}
#include<stdio.h>
#include<algorithm>
#include<vector>
using namespace std;
int main(){
int n, m, k;
while(scanf("%d%d%d", &n, &m, &k) != EOF){
vector<vector<int>> table((n+1), vector<int>(m+1));
vector<vector<double>> P((n+1), vector<double>(m+1));
int x, y;
for(int i = 0; i < k; i++){
scanf("%d%d", &x, &y);
table[x][y] = 1;
}
P[1][1] = 1.0; //起点概率为1
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
if(!(i == 1 && j ==1)){ //跳过起点
P[i][j] = P[i-1][j]*(j == m? 1 : 0.5) + P[i][j-1]*(i == n?1:0.5); //边界的时候,概率为1
if(table[i][j] == 1) P[i][j] = 0; //如果该点有蘑菇,概率置为0
}
}
}
printf("%.2lf\n", P[n][m]);
}
}
思路:注意边界就行
一开始用路径错了 看了大家的 直接用概率做
需要判断各种边界
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
//常量区
const int maxn = 25;
int arr[maxn][maxn];
double pro[maxn][maxn];
//函数区
//main函数
int main(){
int N, M, k;
while(scanf("%d%d%d", &N, &M, &k) == 3){
memset(arr, 0, sizeof(arr));
memset(pro, 0, sizeof(pro));
for(int i=0; i<k; i++){
int x, y;
scanf("%d%d", &x, &y);
arr[x][y] = 1;
}
for(int i=1; i<=N; i++)
for(int j=1; j<=M; j++){
if(i==1 && j==1) {pro[i][j] = 1; continue; }
if(arr[i][j]) {pro[i][j] = 0; continue; }
if(i==N && j==M) {pro[i][j] = pro[i-1][j] + pro[i][j-1]; continue;}
if(i == N) {pro[i][j] = pro[i-1][j]*0.5 + pro[i][j-1]; continue;}
if(j == M) {pro[i][j] = pro[i-1][j] + pro[i][j-1]*0.5; continue;}
if(i == 1) {pro[i][j] = pro[i][j-1]*0.5; continue;}
if(j == 1) {pro[i][j] = pro[i-1][j]*0.5; continue;}
pro[i][j] = pro[i][j-1]*0.5 + pro[i-1][j]*0.5;
}
printf("%.2lf\n", pro[N][M]);
}
return 0;
}