马踏棋盘算法(骑士周游问题)
定义:将马随机放在国际象棋的8×8棋盘Board[0~7][0~7]的某个方格中,马按走棋规则进行移动。要求每个方格只进入一次,走遍棋盘上全部64个方格。
算法:如图:
这里的算法和矩阵中的路径一题非常相似,都是使用回溯法。
#include <iostream>
using namespace std;
#include <time.h>
#define N 64
int pathlength[N];
bool hasPath(int *chess,int rows,int cols);
bool hasPathCore(int *chess,int rows,int cols,int row,int col,int &pathnum,bool *visited);
int main()
{
int chess[N];
int rows = 8;
int cols = 8;
time_t start,end;
start = time(NULL);
if (hasPath(chess,rows,cols))
cout << "成功" << endl;
end = time(NULL);
for (int i=0;i < N;i ++)
{
cout << pathlength[i] << " ";
}
cout << endl;
system("pause");
return 0;
}
bool hasPath(int *chess,int rows,int cols)
{
if (chess==nullptr || rows < 1 || cols < 1)
{
return false;
}
bool *visited = new bool[N];
memset(visited,0,N);
int pathnum = 0;
for (int row = 0;row < rows;row ++)
{
for (int col = 0;col < cols;col++)
{
if (hasPathCore(chess,rows,cols,row,col,pathnum,visited))
{
return true;
}
}
}
delete[]visited;
return false;
}
bool hasPathCore(int *chess,int rows,int cols,int row,int col,int &pathnum,bool *visited)
{
if (pathnum==N)
{
return true;
}
bool haspath = false;
if (row >=0 && col >=0 && row < rows && col < cols && !visited[row*cols+col])
{
pathlength[pathnum] = row*cols+col;
pathnum++;
visited[row*cols+col] = true;
haspath = hasPathCore(chess,rows,cols,row+2,col+1,pathnum,visited)
|| hasPathCore(chess,rows,cols,row+1,col+2,pathnum,visited)
|| hasPathCore(chess,rows,cols,row-1,col+2,pathnum,visited)
|| hasPathCore(chess,rows,cols,row-2,col+1,pathnum,visited)
|| hasPathCore(chess,rows,cols,row-2,col-1,pathnum,visited)
|| hasPathCore(chess,rows,cols,row-1,col-2,pathnum,visited)
|| hasPathCore(chess,rows,cols,row+1,col-2,pathnum,visited)
|| hasPathCore(chess,rows,cols,row+2,col-1,pathnum,visited);
if (!haspath)
{
pathnum--;
visited[row*cols+col] = false;
}
}
return haspath;
}