回溯法解决马步遍历问题
设计一算法,求解国际象棋中的马的周游问题:给定一8×8的棋盘,马从棋盘的某个位置出发,经过棋盘中的每一个方格恰好一次。(只需求一可行解)
一、 算法思想描述
指定一个起点坐标,从起点开始对每个点遍历其能到达的八方向上的点,如果可以踩则走到该结点上,并继续深入遍历,直到最后走完所有的结点。
二、 完整的程序以及说明
-
#include<iostream>
-
using namespace std;
-
-
// 棋盘大小
-
#define N 8
-
-
// 八方向
-
#define DIR 8
-
int dir[DIR][2] = { {2,1}, {1,2}, {-1,2}, {-2,1}, {-2,-1}, {-1,-2}, {1,-2}, {2,-1} };
-
-
int mz[N][N];
-
bool flag;
-
int sx, sy;
-
-
/**
-
* 遍历算法
-
* 输入: 起点坐标
-
*/
-
void chess(int x, int y, int t){
-
// 标记这格走完了
-
mz[x][y] = t;
-
-
// 走完N*N格
-
if(t==N*N){
-
// 标记找到了路径
-
flag = true;
-
-
for(int i=0; i<N; i++){
-
for(int j=0; j<N; j++){
-
printf("%5d", mz[i][j]);
-
}
-
putchar('\n');
-
}
-
-
return;
-
-
}
-
-
// 八方向可以走到的格子
-
for(int i=0; i<DIR&&!flag; i++){
-
int tx = x+dir[i][0];
-
int ty = y+dir[i][1];
-
-
// 如果存在该格并且没走过
-
if(tx>=0&&tx<N&&ty>=0&&ty<N&&!mz[tx][ty]){
-
// 走进去
-
chess(tx,ty,t+1);
-
}
-
}
-
-
// 还原状态
-
mz[x][y] = 0;
-
}
-
-
-
int main(){
-
int x,y;
-
-
memset(mz,0,sizeof(mz));
-
-
cout<<"请输入起点坐标(从(1,1)至("<<N<<","<<N<<")):";
-
cin>>x>>y;
-
-
x--, y--;
-
-
sx = x, sy = y;
-
-
// 寻路标记置为false
-
flag = false;
-
-
// 从(x,y)开始寻路
-
chess(x,y,1);
-
-
if(!flag)puts("找不到可行路径!");
-
-
return 0;
-
}
2012年12月18日 14:19
NICE WORK~~