马的周游路线(knight's tour)讲的是在一个国际象棋棋盘上,让一匹马用64步跳完64个格子的问题。
我这个算法是按照深度优先算法搜索整个解空间,虽然对于 8*8 的棋盘时间消耗上还算很短,但其效率绝对还是不高的。
后来看了易语言的示例,发现其实可以用贪心算法来找到马的周游路线,就是每次都走到剩下可行的步数最少的格子去——但是不理解原理。
#include <iostream>
using namespace std;
#define SIZE 8
#define EMPTY -1
#define OUT -2
#define NO_MOVE -1
const int move_to[8][2]={ //这个似乎很巧妙,换一下顺序它就慢了
{ 1, -2},
{-1, -2},
{ 2, -1},
{-2, -1},
{ 2, 1},
{-2, 1},
{ 1, 2},
{-1, 2}
};
class DAMNED_knight
{
struct point{int x;int y;};
int steps;
int board[2+SIZE+2][2+SIZE+2]; // 搜索时怕下标越界…呃,肯定是要”越“的了
point step_list[SIZE*SIZE];
public:
DAMNED_knight()//构造函数,初始化
{
steps=0;
for(int i=0;i<SIZE+4;i++)
for(int j=0;j<SIZE+4;j++)
board[i][j]=OUT;
for(int i=2;i<SIZE+2;i++)
for(int j=2;j<SIZE+2;j++)
board[i][j]=EMPTY;
for(int i=0;i<SIZE*SIZE;i++)
{
step_list[i].x=NO_MOVE;
step_list[i].y=NO_MOVE;
}
}
bool search(int x,int y)
{
if (board[x][y]!=EMPTY) {return false;}
board[x][y]=steps+1;
step_list[steps].x=x;
step_list[steps].y=y;
steps++;
if (steps==SIZE*SIZE) return true;
for (int i=0;i<8;i++)
if(search(x+move_to[i][0],y+move_to[i][1])) return true;
board[x][y]=EMPTY;
steps--;
return false;
}
void GO(int x,int y)
{
if(search(x+2,y+2))
{
for (int i=0;i<SIZE*SIZE;i++) cout<<i+1<<":/t"<<step_list[i].x-2<<','<<step_list[i].y-2<<'/n';
cout<<"-----------------------------------/n";
for (int i=2;i<SIZE+2;i++){
for (int j=2;j<SIZE+2;j++)
cout<<(board[i][j]<10?"0":"")<<board[i][j]<<' ';
cout<<'/n';
}
}
else cout<<"can't find the answer!!!";
}
};
int main()
{
DAMNED_knight a;
a.GO(1,1);
cin.get();
return 0;
}
我这个算法是按照深度优先算法搜索整个解空间,虽然对于 8*8 的棋盘时间消耗上还算很短,但其效率绝对还是不高的。
后来看了易语言的示例,发现其实可以用贪心算法来找到马的周游路线,就是每次都走到剩下可行的步数最少的格子去——但是不理解原理。
#include <iostream>
using namespace std;
#define SIZE 8
#define EMPTY -1
#define OUT -2
#define NO_MOVE -1
const int move_to[8][2]={ //这个似乎很巧妙,换一下顺序它就慢了
{ 1, -2},
{-1, -2},
{ 2, -1},
{-2, -1},
{ 2, 1},
{-2, 1},
{ 1, 2},
{-1, 2}
};
class DAMNED_knight
{
struct point{int x;int y;};
int steps;
int board[2+SIZE+2][2+SIZE+2]; // 搜索时怕下标越界…呃,肯定是要”越“的了
point step_list[SIZE*SIZE];
public:
DAMNED_knight()//构造函数,初始化
{
steps=0;
for(int i=0;i<SIZE+4;i++)
for(int j=0;j<SIZE+4;j++)
board[i][j]=OUT;
for(int i=2;i<SIZE+2;i++)
for(int j=2;j<SIZE+2;j++)
board[i][j]=EMPTY;
for(int i=0;i<SIZE*SIZE;i++)
{
step_list[i].x=NO_MOVE;
step_list[i].y=NO_MOVE;
}
}
bool search(int x,int y)
{
if (board[x][y]!=EMPTY) {return false;}
board[x][y]=steps+1;
step_list[steps].x=x;
step_list[steps].y=y;
steps++;
if (steps==SIZE*SIZE) return true;
for (int i=0;i<8;i++)
if(search(x+move_to[i][0],y+move_to[i][1])) return true;
board[x][y]=EMPTY;
steps--;
return false;
}
void GO(int x,int y)
{
if(search(x+2,y+2))
{
for (int i=0;i<SIZE*SIZE;i++) cout<<i+1<<":/t"<<step_list[i].x-2<<','<<step_list[i].y-2<<'/n';
cout<<"-----------------------------------/n";
for (int i=2;i<SIZE+2;i++){
for (int j=2;j<SIZE+2;j++)
cout<<(board[i][j]<10?"0":"")<<board[i][j]<<' ';
cout<<'/n';
}
}
else cout<<"can't find the answer!!!";
}
};
int main()
{
DAMNED_knight a;
a.GO(1,1);
cin.get();
return 0;
}