Bootstrap

蓝桥杯----玩具蛇 DFS

  • 蓝桥杯----玩具蛇 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
;