描述
馬在中國象棋以日字形規則移動。
請編寫一段程序,給定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
代碼如下
#include <cstdio>
#include <cstring>
const int N=11;
int chess[N][N],n,m,x0,y0,nm,ans=0;
int zf[8][2]={{1,2},{1,-2},{-1,2},{-1,-2},{2,1},{2,-1},{-2,1},{-2,-1}};
void dfs(int step,int x,int y){
if(step==nm){
ans++;
}else{
for(int i=0;i<8;i++){
int tempx = x + zf[i][0];
int tempy = y + zf[i][1];
if(tempx>=0&&tempx<n&&tempy>=0&&tempy<m&&chess[tempx][tempy]!=1){
chess[tempx][tempy]=1;
dfs(step+1,tempx,tempy);
chess[tempx][tempy]=0;
}
}
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--){
memset(chess,0,sizeof(chess));
scanf("%d%d%d%d",&n,&m,&x0,&y0);
nm=n*m;
ans=0;
chess[x0][y0]=1;
dfs(1,x0,y0);
printf("%d\n",ans);
}
return 0;
}
思路解析
深搜。chess二維數組儲存的是棋盤,開始將chess數組賦值全部為0,0即為馬沒走過的位置。然后將馬的初始位置賦值為1。nm即為棋盤格子數。調用dfs函數。當nm恰好等於step時,說明馬恰好每個格子都走過了。並且沒有重復走。此時ans++,如果沒有相等,就繼續模擬。if里面的條件就是判斷所走的在棋盤中並且尚未走過,那就將此處的位置標記成1,即走過。然后繼續下一層搜索。如果下一層不合法,即走到邊緣或下一步為重復,循環過后返回上一層,那么再將那處位置標記為0,即未走過,因為再往下走不合法嘛,只能回溯。以此思路最終輸出答案ans。
