题目链接:https://www.luogu.org/problem/P1605
题目背景:
给定一个N*M方格的迷宫,迷宫里有T处障碍,障碍处不可通过。给定起点坐标和终点坐标,问: 每个方格最多经过1次,有多少种从起点坐标到终点坐标的方案。在迷宫中移动有上下左右四种方式,每次只能移动一个方格。数据保证起点上没有障碍。
输入格式:
第一行N、M和T,N为行,M为列,T为障碍总数。第二行起点坐标SX,SY,终点坐标FX,FY。接下来T行,每行为障碍点的坐标。
输出格式:
给定起点坐标和终点坐标,问每个方格最多经过1次,从起点坐标到终点坐标的方案总数。
输入输出样例
输入 #1
2 2 1
1 1 2 2
1 2
输出 #1
1
说明/提示
【数据规模】
1≤N,M≤5
分析:此题采用回溯的思想
1. 回溯算法概念:
回溯算法实际上一个类似枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就“回溯”返回,尝试别的路径。
回溯法是一种选优搜索法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。
许多复杂的,规模较大的问题都可以使用回溯法,有“通用解题方法”的美称。
2. 回溯法的基本思想
在包含问题的所有解的解空间树中,按照深度优先搜索的策略,从根结点出发深度探索解空间树。当探索到某一结点时,要先判断该结点是否包含问题的解,如果包含,就从该结点出发继续探索下去,如果该结点不包含问题的解,则逐层向其祖先结点回溯。(其实回溯法就是对隐式图的深度优先搜索算法)。
若用回溯法求问题的所有解时,要回溯到根,且根结点的所有可行的子树都要已被搜索遍才结束。
3. 回溯法递归框架
回溯法是对解空间的深度优先搜索,在一般情况下使用递归函数来实现回溯法比较简单,其中i为搜索的深度,框架如下:
1: int a[n];
2: try(int i)
3: {
4: if(i>n)
5: 输出结果;
6: else
7: {
8: for(j = 下界; j <= 上界; j=j+1) // 枚举i所有可能的路径
9: {
10: if(fun(j)) // 满足限界函数和约束条件
11: {
12: a[i] = j;
13: ... // 其他操作
14: try(i+1);
15: 回溯前的清理工作(如a[i]置空值等);
16: }
17: }
18: }
19: }
c++代码实现:
#include <iostream>
using namespace std;
int pic[6][6];
int dx[4] = {0, 0, -1, 1};
int dy[4]= {-1, 1, 0, 0};
int ans = 0; //计算总的路径数
int N,M,T;
int SX, SY;
int FX, FY;
int temp[6][6];
void dfs(int x,int y)
{
if(x==FX && y == FY)
{
ans++;
return;
}
else
{
for(int i=0;i<4;i++)
{
if(temp[x+dx[i]][y+dy[i]] == 0 && pic[x+dx[i]][y+dy[i]]==1)
{
temp[x][y] = 1;
dfs(x+dx[i], y+dy[i]);
temp[x][y] = 0;
}
}
}
}
int main()
{
cin>>N>>M>>T;
for(int i=1;i<=N;i++)
{
for (int j = 1; j <= M; j++)
{
pic[i][j] = 1;
}
}
cin>>SX>>SY;
cin>>FX>>FY;
for(int i=0;i<T;i++)
{
int t1,t2;
cin>>t1>>t2;
pic[t1][t2] = 0;
}
dfs(SX, SY);
cout<<ans<<endl;
return 0;
}
python3代码实现:
# dx = [0, 1, 0, -1]
# dy = [1, 0, -1, 0]
dx = [0, 0, -1, 1]
dy = [-1, 1, 0, 0]
INIT_ROW = 100
INIT_COL = 100
def walk(x, y):
global count
if x == EX and y == EY:
count += 1
return
else:
for i in range(4):
if temp[x + dx[i]][y + dy[i]] == 0 and pic[x + dx[i]][y + dy[i]] == 1:
temp[x][y] = 1
walk(x + dx[i], y + dy[i])
temp[x][y] = 0
if __name__ == '__main__':
s1 = list(map(int, input().split(' ')))
N, M, T = s1[0], s1[1], s1[2]
s2 = list(map(int, input().split(' ')))
SX, SY, EX, EY = s2[0], s2[1], s2[2], s2[3]
pic = []
temp = []
for i in range(INIT_ROW):
pic.append([0 for i in range(INIT_ROW)])
temp.append([0 for i in range(INIT_COL)])
for i in range(1, N+1):
for j in range(1, M+1):
pic[i][j] = 1
for k in range(T):
row = list(map(int, input().split(' ')))
pic[row[0]][row[1]] = 0
print(pic)
print(temp)
count = 0
walk(SX, SY)
print(count)