【DFS/回溯算法】2016年蓝桥杯真题之路径之谜详解

本文涉及的产品
智能开放搜索 OpenSearch行业算法版,1GB 20LCU 1个月
实时计算 Flink 版,1000CU*H 3个月
实时数仓Hologres,5000CU*H 100GB 3个月
简介: 题目要求根据城堡北墙和西墙箭靶上的箭数,推断骑士从西北角到东南角的唯一路径。每步移动时向正北和正西各射一箭,同一格不重复经过。通过DFS回溯模拟“拔箭”过程,验证路径合法性。已知箭数约束路径唯一,最终按编号输出行走顺序。


1.题目描述:
小明冒充 X 星球的骑士,进入了一个奇怪的城堡。

城堡里边什么都没有,只有方形石头铺成的地面。

假设城堡地面是 n×n 个方格。如图所示。

按习俗,骑士要从西北角走到东南角。

可以横向或纵向移动,但不能斜着走,也不能跳跃。

每走到一个新方格,就要向正北方和正西方各射一箭。

(城堡的西墙和北墙内各有 n 个靶子)

同一个方格只允许经过一次。但不必做完所有的方格。

如果只给出靶子上箭的数目,你能推断出骑士的行走路线吗?

有时是可以的,比如如图中的例子。

本题的要求就是已知箭靶数字,求骑士的行走路径(测试数据保证路径唯一)

输入格式
第一行一个整数 N(0<N<20),表示地面有 N×N 个方格。

第二行 N 个整数,空格分开,表示北边的箭靶上的数字(自西向东)

第三行 N 个整数,空格分开,表示西边的箭靶上的数字(自北向南)

输出格式
一行若干个整数,表示骑士路径。

为了方便表示,我们约定每个小格子用一个数字代表,从西北角开始编号 :0,1,2,3⋯。

比如,图中的方块编号为:

0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15

2.题解:
本题实质上是个DFS问题,根据给定的已知条件:北边和西边箭靶上箭的个数,逆推出路径。可以正向dfs,即设定两个空数组,每走过一个格子北面和西面的箭靶各加1。但在这道题更适合的方法是认为是一道拔箭问题,即每走过一个格子北面和西面的箭靶各减1,条件判断为:不能越界,不能走已经走过的格子,不能走已经满足箭靶上箭个数的格子。接下来设定check函数,用于判断是否走到了终点且满足每个箭靶的数量全部为0(全部拔光了)不满足则返回false,若满足条件,将保存的路径坐标转化为题目要求的输出格式,并返回false(原路恢复原样返回),若未到达终点,返回true。在主体的dfs函数中,首先用check函数检查是否到达了终点(false则return,回到上一层进行回溯,true则跳到else语句)else语句中首先对现有坐标进行上下左右的移动,按循环顺序选择符合条件判断的一个方向移动,接着进行拔箭,保存路径和标记已走过。然后进行递归dfs()进入下一层,在这之后设定回溯初始化,和递归的操作相反,放箭,删除路径和标记未走过,这里的代码是在dfs()执行完之后再去执行的,dfs()执行完说明最下层上下左右尝试过都不行一直return回溯到这一层。main函数里接受输入的数据。对于起点,由于进入dfs的点默认都是经过拔箭,保存路径和标记已走过处理的,因此要在main中提前处理。

3.详细c++代码

include

using namespace std;

struct ball//结果路径坐标容器
{
int first;//横坐标
int second; //纵坐标
};

int n;//行列数

const int N=30;
int row[N];//记录北边靶子的箭数
int col[N];//记录西边靶子的箭数
bool flag[N][N];

//上下左右的方向
int ax[4]={0,1,-1,0};
int ay[4]={1,0,0,-1};

//用来保存路径 ,xy对
vector res;

bool pd(int dx,int dy)//判断是否符合条件(不能越界,不能走已经走过的格子,不能走已经满足箭靶上箭个数的格子)
{
if(flag[dx][dy]==1)
return false;
if(dx<0) return false; if(dx>n-1)
return false;
if(dy<0) return false; if(dy>n-1)
return false;
if(row[dy]<=0)
return false;
if(col[dx]<=0)
return false;

return true;

}

bool check(int dx,int dy)//仅当走到终点时使用:检查箭是否全部拔光,若全部拔光输出结果。不管怎么样全部return false(用来回溯)
{
if(dx==(n-1)&&dy==(n-1))
{
for(int i=0;i<n;i++)
{
if(row[i]!=0)
return false; //北面的箭全部拔光
}

    for(int i=0;i<n;i++)
    {
        if(col[i]!=0)//西面的箭全部拔光 
        return false; 
    }


    for(int i=0;i<res.size();i++)//按照输出格式输出结果 
    {
        int hx=res[i].first;
        int hy=res[i].second;
        int sum=n*hx+hy;
        cout<<sum<<" ";
    }

    return false;
}

return true;

}

void dfs(int dx,int dy)
{
if(check(dx,dy)==false)//检查走到终点时路径是否正确
{
return;//回溯返回
}
else
{
for(int i=0;i<4;i++)
{
int x=dx+ax[i];
int y=dy+ay[i];
if(pd(x,y)==false) //检查是否符合条件
{
continue;
}
else
{
flag[x][y]=1;
row[y]--;col[x]--;
res.push_back({x,y});//拔箭,保存路径和标记已走过

            dfs(x,y);//递归 

            res.pop_back();
            row[y]++;col[x]++;
            flag[x][y]=0;//回溯返回后恢复原状 

        } 
    }
}

}

int main()
{
//接受数据
cin>>n;
for(int i=0;i>row[i];
}
for(int i=0;i>col[i];
}

 //对于起点,由于进入dfs的点默认都是经过拔箭,保存路径和标记已走过处理的,因此要在main中提前处理
flag[0][0]=1;
col[0]--;
row[0]--;
res.push_back({0,0});
dfs(0,0);

 return 0;

}

感谢大家的观看!!!别忘记点赞哦!!!

相关文章
|
3月前
|
传感器 机器学习/深度学习 编解码
MATLAB|主动噪声和振动控制算法——对较大的次级路径变化具有鲁棒性
MATLAB|主动噪声和振动控制算法——对较大的次级路径变化具有鲁棒性
203 3
|
4月前
|
算法 机器人 定位技术
【VRPTW】基于matlab秃鹰算法BES求解带时间窗的骑手外卖配送路径规划问题(目标函数:最优路径成本 含服务客户数量 服务时间 载量 路径长度)(Matlab代码实现)
【VRPTW】基于matlab秃鹰算法BES求解带时间窗的骑手外卖配送路径规划问题(目标函数:最优路径成本 含服务客户数量 服务时间 载量 路径长度)(Matlab代码实现)
127 0
|
4月前
|
算法
回溯算法的基本思想
本节介绍回溯算法,通过图1中从A到K的路径查找示例,说明其与穷举法的异同。回溯算法通过“回退”机制高效试探各种路径,适用于决策、优化和枚举问题。
112 0
|
3月前
|
机器学习/深度学习 传感器 算法
【无人车路径跟踪】基于神经网络的数据驱动迭代学习控制(ILC)算法,用于具有未知模型和重复任务的非线性单输入单输出(SISO)离散时间系统的无人车的路径跟踪(Matlab代码实现)
【无人车路径跟踪】基于神经网络的数据驱动迭代学习控制(ILC)算法,用于具有未知模型和重复任务的非线性单输入单输出(SISO)离散时间系统的无人车的路径跟踪(Matlab代码实现)
205 2
|
3月前
|
机器学习/深度学习 传感器 算法
基于全局路径的无人地面车辆的横向避让路径规划研究[蚂蚁算法求解](Matlab代码实现)
基于全局路径的无人地面车辆的横向避让路径规划研究[蚂蚁算法求解](Matlab代码实现)
203 8
|
3月前
|
算法 数据挖掘 区块链
基于遗传算法的多式联运车辆路径网络优优化研究(Matlab代码实现)
基于遗传算法的多式联运车辆路径网络优优化研究(Matlab代码实现)
115 2
|
3月前
|
机器学习/深度学习 算法 机器人
【机器人路径规划】基于深度优先搜索(Depth-First-Search,DFS)算法的机器人路径规划(Python代码实现)
【机器人路径规划】基于深度优先搜索(Depth-First-Search,DFS)算法的机器人路径规划(Python代码实现)
242 3
|
3月前
|
存储 算法 数据可视化
基于禁忌搜索算法的TSP问题最优路径搜索matlab仿真
本程序基于禁忌搜索算法解决旅行商问题(TSP),旨在寻找访问多个城市的最短路径。使用 MATLAB 2022A 编写,包含城市坐标生成、路径优化及结果可视化功能。通过禁忌列表、禁忌长度与藐视准则等机制,提升搜索效率与解的质量,适用于物流配送、路径规划等场景。
|
3月前
|
机器学习/深度学习 负载均衡 算法
【卡车和无人机协同配送路径优化】遗传算法求解利用一辆卡车和两架无人机配合,将小包裹递送给随机分布的客户,以使所有站点都由卡车或无人机递送一次后返回起始位置(中转站)研究(Matlab代码实现)
【卡车和无人机协同配送路径优化】遗传算法求解利用一辆卡车和两架无人机配合,将小包裹递送给随机分布的客户,以使所有站点都由卡车或无人机递送一次后返回起始位置(中转站)研究(Matlab代码实现)
248 7
|
3月前
|
机器学习/深度学习 传感器 算法
基于matlab瞬态三角哈里斯鹰算法TTHHO多无人机协同集群避障路径规划(目标函数:最低成本:路径、高度、威胁、转角)(Matlab代码实现)
基于matlab瞬态三角哈里斯鹰算法TTHHO多无人机协同集群避障路径规划(目标函数:最低成本:路径、高度、威胁、转角)(Matlab代码实现)
134 1