数据结构-马走日的解法

假设国际象棋棋盘有5*5共25个格子。设计一个程序,使棋子从初始位置(如图)开始跳马,需要将棋盘的格子全部都走一遍,每个格子只允许走一次。

问:总共有多少解。(提示:回溯法)

P.S国际象棋的棋子是在格子中间的。国际象棋中的“马走日”,如第一步为[1,1],第二步为[2,8]或[2,12],第三步可以是[3,5]或[3,21]等,以此类推。

#include <iostream>
using namespace std;

const int m = 5, n = 5;
int countN = 0;
int trace[m][n] = { 0 };
int changedir[][2] = { {1,2},{2,1},{1,-2},{2,-1},{-1,2},{-2,1},{-1,-2},{-2,-1} };

void printT()
{
	for (int i = 0; i < m; i++)
	{
		for (int j = 0; j < n; j++)
		{
			cout << trace[i][j] << '	';
		}
		cout << endl;
	}
	cout << "------------" << endl;
}

void visit(int x, int y, int step)
{
	trace[x][y] = step;
	//printT();
	if (m*n == step)
	{
		countN++;
		printT();
		return;
	}
	int nextx, nexty;
	for (int i = 0; i < 8; i++)
	{
		nextx = x + changedir[i][0];
		nexty = y + changedir[i][1];
		if (nextx < 0 || nextx>(m-1) || nexty < 0 || nexty>(n-1)|| trace[nextx][nexty]!=0)
		{
			continue;
		}
		visit(nextx, nexty, step + 1);
		trace[nextx][nexty] = 0;
	}
}



void main()
{

	int firstX , firstY ;
	cout << "输入起始位置(棋盘的左上角编号位置(0,0)):" << endl;
	cin >> firstX >> firstY;
	//printT();
	visit(firstX, firstY, 1);
	cout << "Count " << countN << endl;
}

思考:此题也是递归回溯的思想。当确定一个位置之后,要考虑8种可以跳马的方向,设置一个记步数的变量step,当step为25时退出递归,同时把最后确定的一个位置,即写着25的格子的变量重置为0,同时退回到第24步,去寻找其它第25步的可能位置。

结果:

原文地址:https://www.cnblogs.com/oneDongHua/p/14264044.html