/** * function:马的遍历。在8x8方格的棋盘上,从任意指定的方格出发, * 为马寻找一条走遍棋盘每一格并且只经过一次的一条路径。 * author:顾博君 * time:2013-1-23 */ /* * 采用Warnsdoff策略求解。找出出口最少的点。 * --------------------- | | 4 | | 3 | | --------------------- | 5 | | | | 2 | --------------------- | | | · | | | --------------------- | 6 | | | | 1 | --------------------- | | 7 | | 0 | | --------------------- */ #include <stdio.h> #include <windows.h> #define N 8 //棋盘大小 int delta_i[]={ 2, 1,-1,-2,-2,-1, 1, 2};//马的8中走棋方式 int delta_j[]={ 1, 2, 2, 1,-1,-2,-2,-1}; int board[N][N];//棋盘 int exitn(int i,int j,int s,int a[]){ //s用于改变a[]数组内容的顺序 int i1,j1,k,count; for(count=k=0;k<N;k++){ //求出下一个点 i1=i+delta_i[(s+k)%N]; j1=j+delta_j[(s+k)%N]; //判断这个点是否在棋盘内并且没有走过 if(i1>=0 && i1<N && j1>=0 && j1<N && board[i1][j1]==0) a[count++]=(s+k)%N;//记录下这个点在数组中的下标 } return count;//返回可以走的下一个点的个数 } int next(int i,int j,int s){ int m;//记录可以走的下一个点的个数 int k,kk,min,a[N],b[N],temp; m=exitn(i,j,s,a); if(m==0) return -1;//如果没有可以走的点,返回-1 for(min=N+1,k=0;k<m;k++){//找出口最少的点 temp=exitn(i+delta_i[a[k]],j+delta_j[a[k]],s,b); if(temp<min){ min=temp; kk=a[k]; } } return kk;//返回出口最少的点 } int main(){ int sx,sy,i,j,step,no,start; //开始遍历所有的点。 for(sx=0;sx<N;sx++){ for(sy=0;sy<N;sy++){ //开始寻找以(sx,sy)为入口的路径 start=0; do{ //棋盘初始化 for(i=0;i<N;i++){ for(j=0;j<N;j++){ board[i][j]=0; } } board[sx][sy]=1;//在棋盘上记录步数 //更新当前点 i=sx;j=sy; for(step=2;step<N*N;step++){ if((no=next(i,j,start))==-1)break;//找下一个点 //更新当前点 i+=delta_i[no]; j+=delta_j[no]; board[i][j]=step;//在棋盘上记录步数 } //if(step>N*N)break; start++;//可能出口的选择顺序 }while(step<N*N); printf("起始点:(%d,%d)\n",sx,sy); //打印棋盘 for(i=0;i<N;i++){ for(j=0;j<N;j++){ printf("%4d",board[i][j]); } printf("\n\n"); } scanf("%*c"); system("cls"); } } }