1. 程式人生 > >百練4123:馬走日

百練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時,即表示找到了一條遍歷棋盤所有點的路徑。

注:在(uv)處對其周圍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;

}

提交結果如下: