题目概述:
题目描述
张三是一个玩迷宫的高手,天下还没有能难住他的迷宫。但是总有人喜欢刁难蒜头君,不停的给张三出难题。这个出题的人很聪明,他知道天下还没有能难住张三的迷宫。
所以他便转换思维问张三,在不走重复路径的情况下,总共有多少不同可以到达终点的路径呢?张三稍加思索便给出了答案,你要不要也来挑战一下?
输入格式
第一行输入两个整数 n(1 ≤ n ≤ 11), m(1 ≤ m ≤ 11),表示迷宫的行和列。
然后有一个 n × m 的地图,地图由 '.'、'#'、's'、'e' 这四个部分组成。'.'表示可以通行的路,'#'表示迷宫的墙,'s'表示起始点,'e'表示终点。
输出格式
输出一个整数,表示从 's' 到达 'e' 的所有方案数。
输入样例1
输入
3 3
##s
#..
e.#
输出
1
输入样例2
输入
3 3
##s
...
e.#
输出
2
输入样例3
输入
5 5
s####
.####
.####
.####
....e
输出
1
输入样例4
输入
5 5
s####
.####
.####
.####
..##e
输出
0
输入样例5
输入
6 6
s...##
.#..##
.#..##
.#....
.#....
.....e
输出
357
思路:
在真实举办的迷宫游戏中,有些商家为了降低游戏的难度可能会赠与玩家空白的方格纸,当玩家无法前进时可以在方格纸对应的位置打上标志表示此路不通。同样我们可以定义两个二维数组,第一个数组记录真实的地图,第二个数组作为“方格纸”使用,同样可以将s,e在数组中的位置记录在全局变量,同样的为了方便可以在主函数外定义一个count = 0,来记录迷宫的方案数,lx,ly作为迷宫的规模,因为迷宫可以选择上下左右,所以需要额外额外定义一个二维数组来储存下一步的方向,走过的地方就在方格纸上标志为1,表示不需要再走一遍,如果接下来上下左右都走不通退回上一步,并且把本步所处位置的方格还原成0,遇到终点count就加1,表示找到一种方案。
具体代码:
#include<stdio.h>
char maza[100][100];//储存真实地图。
int visited[100][100] = { 0 };//标记走过的路。
int startx = 0, starty = 0;//起点位置。
int endx = 0, endy = 0;//终点位置。
int lx = 0, ly = 0;//地图的规模。
int dir[4][2] = {{1,0},{-1,0},{0,-1},{0,1}};//方向数组。
int count = 0;//计数器。
void dfs(int x, int y)
{
if (x == endx && y == endy)
{
count++;
return;
}//如果走到终点,计数器加1,并且返回上一步。
int tx, ty;//定义下一步的位置。
for (int i = 0; i < 4; i++)
{
tx = x + dir[i][0];
ty = y + dir[i][1];//四个方向依次遍历。
if (tx < 0 || tx >= lx || ty < 0 || ty >= ly)
continue;//如果下一步不在迷宫范围内,则继续循环,不进行下一步。
if (visited[tx][ty] == 0 && maza[tx][ty] != '#')//如果下一步没有走过并且不为墙,就将下一步的位置标记为1,表示已经走过。
{
visited[tx][ty] = 1;
dfs(tx, ty);//接着进行下一步。
visited[tx][ty] = 0;//将该位置还原成0
}
}
return;
}
int main(void)
{
scanf("%d%d", &lx, &ly);
char c;
scanf("%c", &c);//处理换行符。
for (int i = 0; i < lx; i++)
{
for (int j = 0; j < ly; j++)
{
scanf("%c", &maza[i][j]);
if (maza[i][j] == 's')
{
startx = i;
starty = j;//如果输入s,则记录s的位置。
}
if (maza[i][j] == 'e')
{
endx = i;
endy = j;//如果输入e,则记录e的位置。
}
}
scanf("%c", &c);//处理换行符。
}
visited[startx][starty] = 1;//起点标志为1.
dfs(startx, starty);
printf("%d", count);
}
注意点:
这段代码需要注意的是一定要将起点的位置提前设置为1,我们可以想象一下,假设我们从起点出发,发现上面可以走,等我们走到上面后,将此地标记为1,然后循环方向数组发现下面(起点)也可以走,就又回到了起点,同时将上面的位置还原成0,然后发现上面又可以走了......,
也就是说如果不提前将起点置1,则会陷入死循环,将这点搞懂,这段代码就很容易理解了。