题目描述
马走日,现在问给定一个坐标,问有多少种方法能够将整个棋盘全部走一遍,不走重复。
输入格式
输出格式
数据范围
1
≤
T
≤
9
,
1≤T≤9,
1≤T≤9,
1
≤
m
,
n
≤
9
,
1≤m,n≤9,
1≤m,n≤9,
0
≤
x
≤
n
−
1
,
0≤x≤n−1,
0≤x≤n−1,
0
≤
y
≤
m
−
1
0≤y≤m−1
0≤y≤m−1
输入样例
1
5 4 0 0
输出样例
32
算法
注意这题,马是走在格子里的,本题考查DFS的顺序,同时特别注意DFS参数对应的含义,下面我会说明,写题时自己遇到的坑,希望有所帮助。
#include <bits/stdc++.h>
using namespace std;
const int N = 20;
int dx[8]={2,1,-1,-2,-2,-1,1,2};//方向数组
int dy[8]={1,2,2,1,-1,-2,-2,-1};//方向数组
int n, m, res;
bool st[N][N];
void dfs(int x, int y, int c) { // 从x, y走,目前还要走c部
if (c == 0) {
res ++;
return ;
}
st[x][y] = true;
for (int i = 0; i < 8; ++ i) {
int xx = dx[i] + x, yy = dy[i] + y;
if (0 <= xx && xx < n && 0 <= yy && yy < m && !st[xx][yy]) {
dfs(xx, yy, c - 1);
}
}
st[x][y] = false;
}
int main() {
int T;
scanf("%d", &T);
while (T --) {
int x, y;
scanf("%d%d%d%d", &n, &m, &x, &y);
res = 0;
dfs(x, y, m * n - 1); // 这里特别注意需要减一,因为这种DFS当c==1时是进不到下一层的,因为无路可走了,所以当时一直输出0,T...T
cout << res << endl;
}
}
下面还有一种写法
#include <bits/stdc++.h>
using namespace std;
const int N = 20;
int dx[8]={2,1,-1,-2,-2,-1,1,2};//方向数组
int dy[8]={1,2,2,1,-1,-2,-2,-1};//方向数组
int n, m, res;
bool st[N][N];
void dfs(int x, int y, int c) { // 从x, y走,目前还要走c部
if (c == 0) {
res ++;
return ;
}
for (int i = 0; i < 8; ++ i) {
int xx = dx[i] + x, yy = dy[i] + y;
if (0 <= xx && xx < n && 0 <= yy && yy < m && !st[xx][yy]) {
st[xx][yy] = true;
dfs(xx, yy, c - 1);
st[xx][yy] = false;
}
}
}
int main() {
int T;
scanf("%d", &T);
while (T --) {
int x, y;
scanf("%d%d%d%d", &n, &m, &x, &y);
res = 0;
st[x][y] = true;
dfs(x, y, m * n - 1);
st[x][y] = false;
cout << res << endl;
}
}