1 条题解

  • 0
    @ 2025-4-9 21:39:33

    题意分析

    这道题目描述了一个经典的网格路径计数问题:

    我们有一个R行S列的网格地图

    每个格子可能是空地(.)或墙壁(#)

    从左上角(1,1)出发,只能向右或向下移动

    需要计算到右下角(R,S)的所有可能路径数

    路径必须恰好使用R+S-2步(即不能绕路)

    不能穿过任何墙壁格子

    解题思路

    动态规划解法

    这是一个典型的动态规划问题,可以使用DP表格来记录到达每个格子的路径数:

    状态定义:

    dp[i][j]dp[i][j]表示从起点(1,1)(1,1)(i,j)(i,j)的路径数

    转移方程:

    如果当前格子是空地:dp[i][j]=dp[i1][j]+dp[i][j1]dp[i][j] = dp[i-1][j] + dp[i][j-1]

    如果是墙壁:dp[i][j]=0dp[i][j] = 0

    边界条件:

    dp[1][1]=1(起点)dp[1][1] = 1(起点)

    第一行和第一列需要特殊处理(只能从一个方向来)

    算法优化

    空间优化:可以使用滚动数组将空间复杂度从O(R×S)降到O(S)

    大数处理:路径数可能很大,可能需要使用高精度计算(但题目没有明确说明数据范围)

    注意事项

    输入处理要小心,注意行列的起始索引

    墙壁的判断要准确

    注意边界条件的处理

    代码实现分析

    给出的代码实现了基本的DP解法:

    初始化:

    清空DP表格

    起点dp[1][1]初始化为1

    DP填充:

    双重循环遍历每个格子

    如果是空地则累加上方和左方的路径数

    跳过起点(已初始化)

    输出结果:

    直接输出右下角格子的DP值

    复杂度分析

    时间复杂度:O(R×S) 每个格子处理一次

    空间复杂度:O(R×S) 存储整个DP表格

    代码实现

    #include<iostream>
    #include<cstdio>
    using namespace std;
    char map[1001][1001];
    int f[1001][1001],i,j,k,n,m,w;
    int main()
    {
    	cin>>k;
    	for (w=1;w<=k;w++)
    	{
    		cin>>n>>m;
    		getchar();
    		for (i=0;i<=n;i++)
    			for (j=0;j<=m;j++)
    				f[i][j]=0;
    		for(i=1;i<=n;i++)
    			cin.getline(map[i]+1,1001);  
    		f[1][1]=1;
    		for (i=1;i<=n;i++)
    			for (j=1;j<=m;j++)
    				if (map[i][j]=='.')
    					if (i!=1||j!=1)
    						f[i][j]=f[i-1][j]+f[i][j-1];
    		cout<<"Existuje "<<f[n][m]<<" ruznych cest."<<endl ;
    	}
    	return 0;
    }
    
    • 1

    信息

    ID
    993
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    2
    已通过
    1
    上传者