描述
馬在中國象棋以日字形規則移動。
請編寫一段程序,給定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。