马走日(dfs)

马在中国象棋以日字形规则移动。

请编写一段程序,给定 n \times mn×m大小的棋盘,以及马的初始位置 (x, y)(x,y),要求不能重复经过棋盘上的同一个点,计算马可以有多少途径遍历棋盘上的所有点。

输入格式

第一行为整数 T(T < 10)T(T<10),表示测试数据组数。
每一组测试数据包含一行,为四个整数,分别为棋盘的大小以及初始位置坐标 n,m,x,yn,m,x,y。(0 \le x \le n-1,0 \le y \le m-1, m < 10, n < 100≤x≤n−1,0≤y≤m−1,m<10,n<10)。

输出格式

每组测试数据包含一行,为一个整数,表示马能遍历棋盘的途径总数,00 为无法遍历一次。

Sample 1

InputcopyOutputcopy
1
5 4 0 0
32

 马走日跟别的dfs差不多只不过是定义8各方向!

#include <iostream>
#include <cstring>
using namespace std;
int m,n,sum=0,flag=0;
int book[210][210];
//这8个方向一定定义清楚 
int inext[8][2]= {{1,2},{2,1},{-1,2},{-2,1},{-1,-2},{-2,-1},{1,-2},{2,-1}};
void bian(int x,int y,int cnt)
{
	if(cnt==n*m-1)//步数等于棋盘位置数减一就是遍历一遍了 
	{
		flag=1; //不能缺 
		sum++;
	}
	if(book[x][y]==0)
	{
		book[x][y]=1;//标记用过 
		for(int i=0; i<8; i++)//8个方向 
		{
			int tx=x+inext[i][0];
			int ty=y+inext[i][1];
			if(tx<0||ty<0||tx>m-1||ty>n-1||book[tx][ty]==1) continue;//剪枝 
			bian(tx,ty,cnt+1);
		}

		book[x][y]=0;//回溯 
	}

	return;
}

int main()
{
	int t,x,y;
	cin >> t;
	while(t--)
	{
		sum=0;
		cin >> m >> n >> x >> y;
		memset(book,0,sizeof book);//数组清空 
		bian(x,y,0) ;
		if(flag) cout << sum << endl;
		else cout << "0"<<endl;
	} 


}

 参考:

(3条消息) 马走日(dfs)_小菜鸡加油吧的博客-优快云博客icon-default.png?t=M276https://blog.youkuaiyun.com/lymww/article/details/118830949?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522164834897716782089360334%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=164834897716782089360334&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-1-118830949.142^v5^pc_search_result_cache,143^v6^register&utm_term=%E9%A9%AC%E8%B5%B0%E6%97%A5&spm=1018.2226.3001.4187

### C语言实现马走问题的深度优先搜索(DFS) #### 1. 马走问题简介 马走问题是经典的棋盘覆盖问题之一,要求骑士按照国际象棋中马的移动方式,在给定大小的棋盘上不重复地过每一个格子。该问题可以通过深度优先搜索(DFS)来求解。 #### 2. 使用DFS解决问题的方法论 为了有效地利用DFS解决此问题,程序会尝试从起始位置出发,沿着合法路径逐步探索整个棋盘上的所有方格。每当到达一个新的未访问过的方格时,则标记为已访问并继续向下一个方向前进;如果遇到死胡同则回溯至上一步重新选择其他可行的方向直至完成全部遍历或确认无解[^1]。 #### 3. 数据结构设计 - 设计辅助函数判断下一步是否越界以及是否已经访问过; - 利用全局变量保存步数以便于更新每一步的位置坐标。 #### 4. DFS核心逻辑描述 ```c #include <stdio.h> #define N 8 // 棋盘尺寸定义成常量方便修改测试不同规模的情况 int board[N][N]; /* 记录行路线 */ int step_x[] = {2, 1, -1, -2, -2, -1, 1, 2}; /* X轴八个可能的变化值 */ int step_y[] = {1, 2, 2, 1, -1, -2, -2, -1}; /* Y轴对应的八个变化 */ // 函数声明部分省略... void dfs(int x, int y, int move_count); bool is_safe(int nextX, int nextY); /* 主函数入口 */ int main() { memset(board, 0, sizeof(board)); // 设置起点 int startX = 0; int startY = 0; printf("Starting from (%d,%d)\n",startX,startY); board[startX][startY]=1; if (!dfs(startX, startY, 1)) { printf("No solution found\n"); } else { for (int i=0;i<N;++i){ for (int j=0;j<N;++j) printf("%2d ",board[i][j]); putchar('\n'); } } return 0; } /** * @brief 尝试从(x,y)处开始第move次跳跃 * * @param x 当前横坐标 * @param y 当前列坐标 * @param move 已经了几步 */ void dfs(int x, int y, int move) { if(move==N*N){ // 成功完成了所有的跳动次数 return true; } bool success=false; for(int k=0;k<8 && !success ;k++){ int nextX=x+step_x[k]; int nextY=y+step_y[k]; if(is_safe(nextX,nextY)){ board[nextX][nextY]=move+1; success|=dfs(nextX,nextY,move+1); if(!success)// 如果这条路不通就撤销这一步操作准备换另一条路试试看 board[nextX][nextY]=0; } } return success; } ``` 上述代码实现了基于DFS算法框架下对马走问题的具体解决方案。其中包含了必要的边界条件检测(`is_safe`)以防止非法索引访问,并通过递归调用来模拟实际游戏过程中玩家不断试探新位置的行为模式[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值