深度优先搜索
dfs思想
解决当下如何做,下一步如何做和当下如何做一样。
要求
求1~n的全排列。
代码
#include <stdio.h>
#define N 3
int a[10];
int book[10];
void dfs(int step) {
int i;
if (step == N + 1) {
for (i = 1; i <= N; ++i) {
printf("%d ", a[i]);
}
printf("\n");
return;
}
for (i = 1; i <= N; ++i) {
if (book[i] == 0) {
a[step] = i;
book[i] = 1;
dfs(step+1);
book[i] = 0;
}
}
return;
}
int main()
{
dfs(1);
return 0;
}
python 代码
a = [0] * 4
book = [0] * 10
def dfs(step):
if step == 4:
print(a)
return
for i in range(1, 4):
if book[i] == 0:
a[step] = i
book[i] = 1
dfs(step+1)
book[i] = 0
dfs(1)
要求
在括号中填入1~9的数字,使等式成立,每个数字只能使用一次。
[ ][ ][ ] + [ ][ ][ ] = [ ][ ][ ]
代码
#include <stdio.h>
int a[10];
int book[10];
int sum;
void dfs(int step) {
int i;
if (step == 10) {
if (a[1]*100 + a[2]*10 + a[3] + a[4]*100 + a[5]*10 + a[6] == a[7]*100 + a[8]*10 + a[9]) {
sum++;
printf("%d%d%d + %d%d%d = %d%d%d \n", a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9]);
}
return;
}
for (i = 1; i <= 9; ++i) {
if (book[i] == 0) {
a[step] = i;
book[i] = 1;
dfs(step+1);
book[i] = 0;
}
}
}
int main()
{
dfs(1);
printf("%d \n", sum / 2);
return 0;
}
结果
168
python 代码
a = [0] * 10
book = [0] * 10
count = 0
def dfs(step):
global count
if step == 10:
if a[1] * 100 + a[2] * 10 + a[3] + a[4] * 100 + a[5] * 10 + a[6] == a[7] * 100 + a[8] * 10 + a[9]:
print("%d%d%d + %d%d%d = %d%d%d" % tuple(a[1:]))
count = count + 1
return
for i in range(1, 10):
if book[i] == 0:
a[step] = i
book[i] = 1
dfs(step+1)
book[i] = 0
dfs(1)
print(int(count/2))
要求
求迷宫中从坐标(0, 0)到(3,2)最少步数?
0代表路,1代表障碍物,2标识走过的路径,3代表目标点。
代码
#include <stdio.h>
#define N 5
#define M 4
int min = 99999999;
int a[N][M] = {
{0, 0, 1, 0},
{0, 0, 0, 0},
{0, 0, 1, 0},
{0, 1, 3, 0},
{0, 0, 0, 1}
};
void print_a() {
for (int i = 0; i < N; ++i)
{
for (int j = 0; j < M; ++j)
{
printf("%d ", a[i][j]);
}
printf("\n");
}
printf("\n");
}
void dfs(int x, int y, int step) {
if (a[x][y] == 3) {
printf("--------------- step : %d\n", step);
print_a();
if (step < min) {
min = step;
}
return;
}
a[x][y] = 2; // 走过的点标记为2
if((a[x][y+1] == 0 || a[x][y+1] == 3) && y+1 < M) { // right
dfs(x, y+1, step+1);
}
if((a[x+1][y] == 0 || a[x+1][y] == 3) && x+1 < N) { // down
dfs(x+1, y, step+1);
}
if((a[x][y-1] == 0 || a[x][y-1] == 3) && y-1 >= 0) { // left
dfs(x, y-1, step+1);
}
if((a[x-1][y] == 0 || a[x-1][y] == 3) && x-1 >= 0) { // up
dfs(x-1, y, step+1);
}
a[x][y] = 0; // 取消标记
}
int main() {
dfs(0, 0, 0);
printf("min: %d \n", min);
return 0;
}
python 代码
N = 5
M = 4
min = 99999999
a = [[0, 0, 1, 0],
[0, 0, 0, 0],
[0, 0, 1, 0],
[0, 1, 3, 0],
[0, 0, 0, 1]]
def mprint(x):
for i in range(N):
print(x[i])
def dfs(i, j, step):
if a[i][j] == 3:
print("--------------- %d" % step)
mprint(a)
return
if j+1 < M and (a[i][j+1] == 0 or a[i][j+1] == 3):
a[i][j] = 2
dfs(i, j+1, step+1)
if i+1 < N and (a[i+1][j] == 0 or a[i+1][j] == 3):
a[i][j] = 2
dfs(i+1, j, step+1)
if j-1 >= 0 and (a[i][j-1] == 0 or a[i][j-1] == 3):
a[i][j] = 2
dfs(i, j-1, step+1)
if i-1 >= 0 and (a[i-1][j] == 0 or a[i-1][j] == 3):
a[i][j] = 2
dfs(i-1, j, step+1)
a[i][j] = 0
dfs(0, 0, 0)