本文已参与[新人创作礼]活动,一起开启掘金创作之路
题目描述
这是4月19日代码源div2的每日一题。
走不出的迷宫 - 题目 - Daimayuan Online Judge
有一个 H 行 W 列的迷宫(行号从上到下是 1−H,列号从左到右是 1−W),现在有一个由 . 和 # 组成的 H 行 W 列的矩阵表示这个迷宫的构造,. 代表可以通过的空地,# 代表不能通过的墙。
现在有个人从 起点 (1,1) 开始走,他每一步只能往右走一格或者往下走一格,并且他不能跨越迷宫的边界。他会一直走,直到没有可以走的路时停下来。
请问这个人最多可以经过多少个格子?
输入格式 第一行两个整数 H,W,表示迷宫有 H 行 W 列。
接下来一个 H 行 W 列的由 . 和 # 组成的矩阵,表示迷宫的构造。
注意:保证 (1,1) 的位置一定是 .。
输出格式 一个整数,表示最多步数。
输出格式
一个整数,表示最多步数。
样例输入1
3 4
.#..
..#.
..##
样例输出1
4
样例输入2
1 1
.
样例输出2
1
样例输入3
5 5
.....
.....
.....
.....
.....
样例输出3
9
数据规模
对于全部数据保证 1≤H,W≤100
问题解析
我采用的是dp做法,当然bfs也是可以的,但是要注意给每个位置打上标记防止走重复了。
dp数组dp[i] [j]的意思是:当走到i行j列的位置上是,走过的最长路径长度。因为我们每次只能往左走或者往下走,这说明了我们想走到 [i] [j]只能从[i-1] [j]往下走一步得到或者从[i] [j-1]往右走一步得到,所以状态转移方程为:dp[i] [j]=max(dp[i-1] [j],dp[i] [j-1])+1。
但是直接这样写是会有问题的,我们要注意判断一下两个特殊性,
一是当前位置是“#”,此时这位置是无法走到的,所以dp[i] [j]就是0
二是虽然当前是“.”,但却无法走到当前位置的情况,比如这么一个样例:
3 10
..#.......
##........
..........
答案应当是2,但要是我们不判断情况2,答案是会错误的,我们实际能走的地方只有左上角的地方,但是我们之前的计算方法会去计算后面的那些点,但实际上那些点是走不到的。所以我们应该判断一下,如果上方和前方是0(即这两处位置也走不到)那你本身也该是0。
AC代码
#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include<math.h>
#include<set>
#include<numeric>
#include<string>
#include<string.h>
#include<iterator>
#include<map>
#include<unordered_map>
#include<stack>
#include<list>
#include<queue>
#include<iomanip>
#define endl '\n';
typedef long long ll;
typedef pair<int, int> PII;
char c[110][110];
PII que[10000];
int moves[110][110];
int main()
{
cin.sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n, m, res = 1;
string s;
cin >> n >> m;
for (int i = 0; i < n; i++)
{
cin >> s;
for (int j = 0; j < m; j++)
c[i][j] = s[j];
}
moves[0][0] = 1;
for (int i = 1; i < n; i++)
if (c[i][0] == '.')
{
moves[i][0] = moves[i - 1][0] + 1;
res = max(moves[i][0], res);
}
else break;
for (int i = 1; i < m; i++)
if (c[0][i] == '.')
{
moves[0][i] = moves[0][i - 1] + 1;
res = max(res, moves[0][i]);
}
else break;
for (int i = 1; i < n; i++)
for (int j = 1; j < m; j++)
if (c[i][j] == '.')
{
if (moves[i - 1][j] == 0 && moves[i][j - 1] == 0)continue;
moves[i][j] = max(moves[i - 1][j], moves[i][j - 1]) + 1;
res = max(res, moves[i][j]);
}
cout << res;
return 0;
}