C++搜尋與回溯演算法之馬走日(遍歷問題)
阿新 • • 發佈:2019-02-02
馬走日
Description
馬在中國象棋以日字形規則移動。
請編寫一段程式,給定n*m大小的棋盤,以及馬的初始位置(x,y),要求不能重複經過棋盤上的同一個點,計算馬可以有多少途徑遍歷棋盤上的所有點。
Input
第一行為整數T(T < 10),表示測試資料組數。每一組測試資料包含一行,為四個整數,分別為棋盤的大小以及初始位置座標n,m,x,y。(0<=x<=n-1,0<=y<=m-1, m < 10, n < 10)
Output
每組測試資料包含一行,為一個整數,表示馬能遍歷棋盤的途徑總數,0為無法遍歷一次。Sample Input
1 5 4 0 0
Sample Output
32
程式碼
程式碼如下:
#include<cstdio> #include<cmath> #include<cstring> #include<iostream> using namespace std; int r,c; int cnt,tot; int wayr[8]={2,2,1,-1,-2,-2,1,-1},wayc[8]={1,-1,2,2,1,-1,-2,-2}; //進行移動 bool mark[1001][1001]; //判斷該數是否被標記過 bool check(int x,int y) //判斷是否出局 { if(x>=0&&y>=0&&x<r&&y<c) return true; return false; } void search(int x,int y) //搜尋函式 { for(int i=0;i<8;i++) if(check(x+wayr[i],y+wayc[i])&&!mark[x+wayr[i]][y+wayc[i]]) //判斷 { mark[x+wayr[i]][y+wayc[i]]=true; tot++; if(tot==r*c-1) cnt++; search(x+wayr[i],y+wayc[i]); //下一輪迴溯 tot--; mark[x+wayr[i]][y+wayc[i]]=false; //回溯 } } int main() { int t; scanf("%d",&t); while(t--) { cnt=0; int m,n; scanf("%d%d%d%d",&r,&c,&m,&n); if(!check(m,n)) printf("0\n"); else if(r==1&&c==1) printf("1\n"); else { mark[m][n]=true; //標記起點 search(m,n); printf("%d\n",cnt); memset(mark,0,sizeof(mark)); } } }