- 蓝桥杯----玩具蛇 DFS
这是一道蓝桥杯国赛真题,属于典型地DFS算法题。提供C++、python实现。
1.选玩具蛇第一节放置的位置,显然4x4的格子都可以。
2.从玩具蛇第一节出发,调用搜索算法。
3.条件 相邻两节成直线或90° 是为下一节放置的方向只能为相邻的上下左右 四个格子,其中已放过的格子,以及越界时不放置。
实现注意:
1.已放置的路径标注
2.边缘条件的限制(不能越界和放置已放置过的位置)
3.终止条件(已放置完)
C++递归实现:
#include "iostream"
using namespace std;
int dx[4]={1,0,-1,0}; //方向控制
int dy[4]={0,1,0,-1};
int a[4][4]={0};
int n=0;
int main()
{
void dfs(int stay,int x,int y);
int stay=0; //玩具蛇共16节 已放置了stay节
int i,k;
for(i=0;i<4;i++) //对4x4的格子 枚举玩具蛇第一个步放置的所有可能。
{
for(k=0;k<4;k++)
{
a[i][k]=1; //对已放置的格子进行标记
dfs(1,i,k);
a[i][k]=0; //清除标记
}
}
cout<<n;
return 0;
}
void dfs(int stay,int x,int y) //x,y相当于正在放置的格子的坐标
{
int tx,ty;
if(stay==16) //递归终止条件
{
n++;
return;
}
for(int i=0;i<4;i++) //尝试向四个方向放置
{
tx=x+dx[i]; //方向
ty=y+dy[i];
if(a[tx][ty]==1||tx<0||tx>3||ty<0||ty>3) //该格子不可放置 或越界 跳过该方向
continue;
a[tx][ty]=1; // 对已放置的格子进行标记
dfs(stay+1,tx,ty);
a[tx][ty]=0; //清除标记
}
}
python 递归实现:
#控制方向
dx,dy=[1,0,-1,0],[0,1,0,-1]
#方形盒子矩阵
ax=[[0 for _ in range(4)] for _ in range(4)]
n = 0 # 方案数量
def main():
global n
for i in range(4):
for j in range(4):
ax[i][j]=1
dfs(1,i,j)
ax[i][j]=0
return n
def dfs(s,x,y):
global n
#终止条件
if s==16:
n+=1
return
for i in range(4):
tx=x+dx[i]
ty=y+dy[i]
#边界条件
if tx<0 or tx>3 or ty<0 or ty>3 or ax[tx][ty]==1 :
continue
ax[tx][ty]=1
dfs(s+1,tx,ty)
ax[tx][ty] = 0
return
python 非递归实现:
#方形盒子数矩阵
co=[[0 for i in range(4)] for j in range(4)]
#控制方向
dx,dy=[1,0,-1,0],[0,1,0,-1]
def norecursion():
n = 0
for i in range(4):
for j in range(4):
x,y=i,j #当前坐标
s=1 #步长
d=0 #控制方向
co[x][y]=1
node=[] #放入走过的节点的坐标和对应的方向
while d<4 or len(node)>0:
if d>3:
current_node=node.pop(-1)
co[x][y]=0
x,y,d=current_node[0],current_node[1],current_node[2]+1
s-=1
continue
tx,ty=x+dx[d],y+dy[d]
#边界条件
if tx <0 or tx>3 or ty<0 or ty>3 or co[tx][ty]==1 :
d+=1
continue
node.append((x,y,d))
x,y=x+dx[d],y+dy[d]
co[x][y]=1
d=0
s+=1
if s==16: #终止条件
n+=1
current_node = node.pop(-1)
co[x][y] = 0
x, y, d = current_node[0], current_node[1], current_node[2] + 1
s-=1
co[i][j] = 0
return n