【题目链接】
ybt 1219:马走日
OpenJudge NOI 2.5 8465:马走日
【题目考点】
1. 深搜 搜索回溯
【解题思路】
求路径数的问题,要做搜索回溯。每次搜索完成后,要恢复状态。
设方向数组,表示当前可以走到的位置与当前位置的横纵坐标的差值。借助方向数组即可遍历从某位置出发“马走日”可以到达的所有位置。
从起点出发,开始搜索,用参数r记录还剩多少位置未访问。每次从(sx,sy)位置出发,搜索可以从该位置“走日”到达的位置,只要这个位置在棋盘内且没访问过,那么访问该位置,从该位置开始继续搜索。知道剩余位置数为0时,得到一条遍历棋盘每个位置的路线,做计数。最后输出路线数,即为结果。
【题解代码】
解法1:深搜
#include <bits/stdc++.h>
using namespace std;
int n, m, ct;//棋盘为n行m列, ct:遍历方法计数
bool vis[10][10];//vis[i][j]:(i,j)位置是否已访问
int dir[8][2]={{1,2},{1,-2},{-1,2},{-1,-2},{2,1},{2,-1},{-2,1},{-2,-1}};
//从(sx,sy)开始搜索。r:还剩多少位置未遍历
void dfs(int sx, int sy, int r)
{
if(r == 0)//如果每个位置都遍历完
{
ct++;//遍历整个棋盘的路线数加1
return;
}
for(int i = 0; i < 8; ++i)//遍历8个可以从(sx,sy)出发走日到达的位置
{
int x = sx + dir[i][0], y = sy + dir[i][1];
if(x >= 0 && x < n && y >= 0 && y < m && vis[x][y] == false)
{//如果(x,y)在棋盘内,且没访问过
vis[x][y] = true;//访问该位置
dfs(x, y, r-1);//搜索(x,y)位置,剩余未访问的位置数量减1
vis[x][y] = false;//状态还原
}
}
}
int main()
{
int t, x, y;
cin >> t;
while(t--)
{
cin >> n >> m >> x >> y;
ct = 0;//多组数据,注意数据清零
memset(vis, 0, sizeof(vis));
vis[x][y] = true;//访问起始位置
dfs(x, y, n*m-1);//剩下n*m-1个未访问的位置
cout << ct << endl;
}
return 0;
}