具体题意以及讲解参考自:https://blog.csdn.net/lyy289065406/article/details/6647666
该题问马能否不重复走完棋盘所有格子,并且要求马的路径以字典序输出,所以第一步自然是从A1开始,并从A1开始搜索,这题的重点是路径字典序,所以马的搜索顺序如图中所示
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int d[8] = {-2, -2, -1, -1, 1, 1, 2, 2};//写出x轴移动的顺序(x轴从左往右递增,y轴从上往下递增)
int c[8] = {-1, 1, -2, 2, -2, 2, -1, 1};//写出y轴移动的顺序,即第一步就是横向减二,纵向减一
int p, q;
bool a[30][30], flag;
int b[1000][3];//储存马走的步骤
bool check(int x, int y)
{
if(x < 0 || x >= p || y < 0 || y >= q)
return false;
if(a[x][y] == false)
return false;
if(flag == true)//如果已经找到符合条件的路径,则不再进行搜索,否则输出的路径就不是按字典序
return false;
return true;
}
void dfs(int x, int y, int step)
{
b[step][0] = y;
b[step][1] = x;
if(step == p*q)
{
flag = true;
return ;
}
for(int i = 0; i < 8; i++)
{
int nx = x+c[i];
int ny = y+d[i];
if(check(nx, ny))
{
a[nx][ny] = false;
dfs(x+c[i], y+d[i], step+1);
a[nx][ny] = true;//回溯
}
}
}
int main()
{
int t, k;
cin>>t;
k = 1;
while(t--)
{
if(k != 1)
cout<<endl;
cin>>p>>q;
cout<<"Scenario #"<<k<<":"<<endl;
flag = false;
memset(a, true, sizeof(a));
a[0][0] = false;
dfs(0, 0, 1);
if(flag)
{
for(int i = 1; i <= p*q; i++)
{
printf("%c%d", b[i][0]+'A',b[i][1]+1);
}
printf("\n");
}
else
{
cout<<"impossible"<<endl;
}
k++;
}
return 0;
}