<—点个赞吧QwQ
宣传一下算法提高课整理{:target=”_blank”}
马在中国象棋以日字形规则移动。
请编写一段程序,给定 $n\*m$ 大小的棋盘,以及马的初始位置 $(x,y)$,要求不能重复经过棋盘上的同一个点,计算马可以有多少途径遍历棋盘上的所有点。
输入格式
第一行为整数 $T$,表示测试数据组数。
每一组测试数据包含一行,为四个整数,分别为棋盘的大小以及初始位置坐标 $n,m,x,y$。
输出格式
每组测试数据包含一行,为一个整数,表示马能遍历棋盘的途径总数,若无法遍历棋盘上的所有点则输出 0。
数据范围
$1 \\le T \\le 9$,
$1 \\le m,n \\le 9$,
$1 \\le n \\times m \\le 28$,
$0 \\le x \\le n-1$,
$0 \\le y \\le m-1$
输入样例:
1
5 4 0 0
输出样例:
32
思路
我们直接从起点开始暴力搜索,当遍历到的点数等于棋盘大小时,我们就可以把答案$+1$
注意偏移数组要变成马走日的形式。
代码
#include <iostream>
#include <cstring>
using namespace std;
const int N = 10;
int t,n,m,sx,sy,ans = 0;
int dx[] = {1,-1,2,-2,1,-1,2,-2},dy[] = {2,2,1,1,-2,-2,-1,-1};
bool vis[N][N];
void dfs (int x,int y,int t) {
if (t == n * m) {
ans++;
return ;
}
for (int i = 0;i < 8;i++) {
int a = x + dx[i],b = y + dy[i];
if (a < 1 || a > n || b < 1 || b > m || vis[a][b]) continue;
vis[a][b] = true;
dfs (a,b,t + 1);
vis[a][b] = false;
}
}
int main () {
cin >> t;
while (t--) {
ans = 0;
memset (vis,false,sizeof (vis));
cin >> n >> m >> sx >> sy;
sx++,sy++;
vis[sx][sy] = true;
dfs (sx,sy,1);
cout << ans << endl;
}
return 0;
}