题目
总时间限制: 1000ms 内存限制: 65536kB
描述
马在中国象棋以日字形规则移动。
请编写一段程序,给定n*m大小的棋盘,以及马的初始位置(x,y),要求不能重复经过棋盘上的同一个点,计算马可以有多少途径遍历棋盘上的所有点。
输入
第一行为整数T(T < 10),表示测试数据组数。
每一组测试数据包含一行,为四个整数,分别为棋盘的大小以及初始位置坐标n,m,x,y。(0<=x<=n-1,0<=y<=m-1, m < 10, n < 10)
输出
每组测试数据包含一行,为一个整数,表示马能遍历棋盘的途径总数,0为无法遍历一次。
样例输入
1
5 4 0 0
样例输出
32
题意
输入测试数据组数和测试数据(坐标),输出马能遍历棋盘的途径总数。
思路
这是一个用深度优先搜索和递归法解决问题。从马的初始位置开始,通过递归尝试所有8种可能的日字形移动方向,每次移动时检查目标位置是否在棋盘范围内且未被访问过。当成功访问所有格子时计数增加,通过回溯机制取消已访问标记来探索其他路径,最终统计所有可能的完整遍历路径总数。
代码
#include<bits/stdc++.h>
using namespace std;
int t,n,m,x,y,ans=0;
bool c[100][100];//访问标记数组
void d(int a,int b,int sum){//DFS函数
if(sum==n*m){//终止条件:访问完所有格子
ans++;//找到一条完整路径
return;
}
int x1[8]={-2,-2,-1,-1,1,1,2,2};//8个方向的行偏移
int y1[8]={-1,1,-2,2,-2,2,-1,1};//8个方向的列偏移
for(int i=0;i<8;i++){//尝试所有8个方向
int x2=a+x1[i],y2=b+y1[i];//计算新位置
if(x2>=0&&x2<n&&y2>=0&&y2<m&&c[x2][y2]==0){//检查是否在棋盘内且未访问c[x2][y2]=true;//标记为已访问d(x2,y2,sum+1);//递归搜索c[x2][y2]=false;//回溯:取消标记}}
}
int main(){
cin>>t;//读取测试用例数
for(int i=1;i<=t;i++){
cin>>n>>m>>x>>y;//读取棋盘大小和初始位置
for(int i=0;i<n;i++){//初始化访问数组for(int j=0;j<m;j++){c[i][j]=false;}}ans=0;//重置计数器c[x][y]=true;//标记起始位置d(x,y,1);//开始搜索cout<<ans<<endl;//输出结果}return 0;
}