【棋盘问题】-迷宫2

迷宫 - 洛谷


解题思路:

(1)本题为搜索的棋盘问题,需要统计所有的方案数,那么肯定会用到回溯,在一个迷宫中,从起点出发,可以从四种方向走,那么先设置行列号的方向数组的偏移量

(2)创建一个aa二维数组表示地图,标记1的地方为障碍,无法通过,设置一个bool 的vis数组,用来标记,这个点是否走过,如果走过的话标记为1,回溯的时候后退为0

(3)接下来从起点出发,朝着4个方向开始搜索,涉及到方向数组,要记得判断越界,递归的出口为,如果当前的步数已经超过了迷宫可走的格子,那么结束递归,如果此时的位置是终点的位置,那么就方案数加1,结束递归

(4)最后输出方案数即可


#include<bits/stdc++.h>
using namespace std;

int n,m,t;//表示迷宫的 宽长,障碍数量 
int x,y,xx,yy;//表示起点和终点的位置 
int ans;//表示方案数
bool vis[10][10];//表示标记数组 
int aa[10][10];//表示迷宫的地图 

int dx[5]={-1,1,0,0};//表示行号的方向数组 
int dy[5]={0,0,-1,1};//表示列号的方向数组
 
//x表示当前走的步数,a,b表示当前的位置 
void dfs(int x,int a,int b)
{
	if(x>n*m-t)//如果步数超过了迷宫的格子 
	return ;//结束递归 
	
	if(a==xx&&b==yy)//如果当前 位置是终点 
	{
		ans++;//方案数增加 
		return ;//结束递归 
	}
	
	for(int i=0;i<=3;i++)
	{
		int X=a+dx[i];
		int Y=b+dy[i];//形成新的坐标 
		
		if(X>n||X<1||Y>m||Y<1)//判断是否越界 
		continue;
		
		if(aa[X][Y]==0&&vis[X][Y]==0)//如果这个位置不是障碍并且没走过的话 
		{
			vis[X][Y]=1;//保存现场 
			dfs(x+1,X,Y);//开始下一步 
			vis[X][Y]=0;//回溯,恢复现场 
		}
	} 
} 

int main()
{
	int t1,t2;//障碍点的坐标
	 
	cin>>m>>n>>t;
	cin>>x>>y>>xx>>yy;
	
	for(int i=1;i<=t;i++)
	{
		cin>>t1>>t2;
		aa[t1][t2]=1;
	} //设置障碍点为1 
	
	vis[x][y]=1;//起点标记已经走过 
	dfs(1,x,y);
	cout<<ans;//输出方案数 
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以为您解答关于回溯法求解n皇后问题的相关问题。 首先,n皇后问题是一个经典的问题,它的目标是在一个n×n的棋盘上放置n个皇后,使得每个皇后都不能互相攻击(即不能在同一行、同一列或同一对角线上)。回溯法是解决这个问题的一种常见方法。 回溯法是一种通过探索所有可能的解来找到所有的解的算法。当探索到某一步时,如果发现这一步不能得到有效的解,就返回上一步继续探索其他的可能性。这个过程就像是在走迷宫,当发现当前的路径走不通时,就返回上一个岔路口继续探索其他的路径。 在n皇后问题中,可以使用一个n维数组来表示棋盘,数组的每个元素表示该位置是否可以放置皇后。从第一行开始,依次尝试在每一列放置皇后,然后递归到下一行继续尝试。如果当前的放置不合法,则回溯到上一行重新尝试其他的列。 具体的伪代码如下: ``` int n; // 棋盘大小 int queenPos[n]; // 记录每行皇后的位置 // 判断当前放置是否合法 bool isValid(int row, int col) { for (int i = 0; i < row; i++) { if (queenPos[i] == col || abs(queenPos[i] - col) == abs(i - row)) { return false; } } return true; } // 递归搜索所有可能的解 void backtrack(int row) { if (row == n) { // 找到一个解 // 处理解的逻辑 return; } for (int col = 0; col < n; col++) { // 尝试在当前行的每一列放置皇后 if (isValid(row, col)) { queenPos[row] = col; backtrack(row + 1); queenPos[row] = -1; // 回溯 } } } ``` 希望这样的回答能够帮助到您,如果您还有其他问题,请随时提出。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值