1. 程式人生 > >C++搜尋與回溯演算法之馬走日(遍歷問題)

C++搜尋與回溯演算法之馬走日(遍歷問題)

馬走日

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));
		}
	}
}