百練4123:馬走日
百練4123:馬走日
總時間限制:
1000ms
記憶體限制:
1024kB
描述
馬在中國象棋以日字形規則移動。
請編寫一段程式,給定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
解體思路:這是一道深搜的題目,dfs(u,v,step)表示在(u,v)位置處所走的步數,在初始位置為dfs(x,y,0),然後對在(u,v)處所有可能走到的位置分別進行dfs搜尋,注意要進行邊界檢測和是否已訪問檢測(vst陣列進行標記)。
當走到(u,v)步數為n*m-1時,即表示找到了一條遍歷棋盤所有點的路徑。
注:在(u,v)處對其周圍8個點進行搜尋時,我們設定兩個陣列dx[],dy[],遍歷時我們可以寫在迴圈裡,對u+dx[i],v+dy[i]進行搜尋,詳細見程式碼。
C++參考程式碼:
#include "iostream"
#include "cstdio"
#include "cstring"
#include "string"
using namespace std;
int vst[15][15];
int SumStep;
int g_step;
int dx[9]={-1,-2,-2,-1,1,2,2,1};
int dy[9]={-2,-1,1,2,2,1,-1,-2};
int n,m,x,y;
void dfs(int u,int v,int step){
if(step==g_step) {
SumStep++;
return;
}
vst[u][v]=1;
int mx,my;
int i;
for(i = 0;i < 8; i++){
mx = u+dx[i];
my = v+dy[i];
if(mx>=0&&mx<n&&my>=0&&my<m&&vst[mx][my]==0) {
vst[mx][my]=1;
dfs(mx,my,step+1);
vst[mx][my]=0;
}
}
}
int main(){
int t;
scanf("%d",&t);
while(t--){
SumStep=0;
memset(vst,0,sizeof(vst));
scanf("%d%d%d%d",&n,&m,&x,&y);
g_step=m*n-1;
dfs(x,y,0);
cout << SumStep <<endl;
}
return 0;
}
提交結果如下: