题目描述
众所周知,在象棋中马的行走方式如图所示:
X O X O X
O X X X O
X X H X X
O X X X O
X O X O X
其中H代表马的位置,O代表马走一步能到达的位置。
请你找一条路径,让马能够经过所有的方格刚好一次。
注意,马的起点和终点可以在棋盘上的任何点,棋盘编号规则如下图所示:
输入描述
单组数据,第一行为两个整数n,m 描述棋盘的大小。
数据保证:n×m≤26
输出描述
对于每个棋盘,输出一条马遍历完棋盘上所有格点的路径。
如果路径有多条,请输出字典序最小的那条。
如果不存在这样一条路径,输出impossible。
样例输入1
4 3
样例输出1
A1B3C1A2B4C2A3B1C3A4B2C4
样例输入2
2 3
样例输出2
impossible
分析
很常规的一道回溯算法题目通过对马下一步能够到达的地方进行搜索,即可得到答案
我的代码实现
#include<iostream>
#include<string.h>
using namespace std;
int num,let;
int next_x[8]= {-1, 1,-2, 2,-2, 2,-1, 1}; //马能够去的方向,y在前保证字典序
int next_y[8]= {-2,-2,-1,-1, 1, 1, 2, 2};
string ans[26];
int tag[26][26];
int yes=0;
void dfs(int k,int x,int y)
{
if(k==num*let)
{
yes=1;
for(int i=0; i<k; i++)
{
cout<<ans[i];
}
exit(0);
}
else
{
for(int i=0; i<8; i++)
{
int nx=x+next_x[i];
int ny=y+next_y[i];
if(nx>=0&&nx<num&&ny>=0&&ny<let&&tag[nx][ny]==0)//符合条件就向下一个方向搜索
{
tag[nx][ny]=1;
ans[k]=char('A'+ny)+to_string(nx+1);
dfs(k+1,nx,ny);
tag[nx][ny]=0;
}
}
}
}
int main()
{
cin>>num>>let;
//起始点
tag[0][0]=1;
ans[0]=char('A'+0)+to_string(1);
dfs(1,0,0);
tag[0][0]=0;
if(yes==0)
{
cout<<"impossible";
}
}