8465:马走日

题目

总时间限制: 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;
}
posted @ 2025-09-20 21:03  骁翊  阅读(15)  评论(1)    收藏  举报