A Knight‘s Journey dfs+回溯

题目大概意思:
在一个棋盘中m*n,马从任意位置出发,马是走日的,输入有多组m,n,要求判断是否马可以吧棋盘上每个位置都走到,可以的话打印路径,要求字典序最小,不能就打印impossible.

思路:
深搜+回溯
马是走日的,一共八种组合,要求路径是字典序最小,横坐标是ABCD…纵坐标是12345… 字典序最序最小就得优先y,y从小到大, x就与y对应,也是小的在前
int dx[8] = {-1,1,-2,2,-2,2,-1,1};
int dy[8] = { -2, -2, -1, -1, 1, 1, 2, 2 };
由于是字典序最小,所以必须得从A1开始,
按照图中的顺序:
在这里插入图片描述

#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;

const int maxn = 27;
struct step{
	char x, y;
}path[maxn];
int m, n;
int cases;
int visited[maxn][maxn];
bool isSuccess;
void dfs(int i, int j, int num);
//为了让路径字典序最小,ABCD优先,所以是往左走,是优先的
int dx[8] = {-1,1,-2,2,-2,2,-1,1};
int dy[8] = { -2, -2, -1, -1, 1, 1, 2, 2 };
int main()
{
	cin >> cases;
	for (int i = 1; i <=cases; i++)
	{
		cin >> m >> n;
		memset(visited, 0, sizeof(visited));
		isSuccess = false;
		visited[1][1] = 1; //起点
		dfs(1, 1, 1);
		printf("Scenario #%d:\n", i);
		if (isSuccess)
		{
			for (int i = 1; i <= m * n; i++)
				printf("%c%c", path[i].y, path[i].x);
			printf("\n");
		}
		else
			printf("impossible\n");
		if (i != cases)
		{
			cout << endl;
		}
	}
}
void dfs(int x, int y, int num)
{
	//添加到路径中
	path[num].y = y + 'A' - 1;
	path[num].x = x + '0';
	if (num == m*n){
		//已经全部遍历完
		isSuccess = true;
		return;
	}
	for (int i = 0; i < 8; i++)
	{
		//遍历下一个位置
		int nx = x + dx[i];
		int ny = y + dy[i];
		if (0 < nx&&nx <= m && 0 < ny&&ny <= n&&!visited[nx][ny] && !isSuccess)
		{
			//访问这个点
			visited[nx][ny] = 1;
			dfs(nx, ny, num + 1);
			//撤销
			visited[nx][ny] = 0;
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值