/**
* 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");
}
}
}
马的遍历(贪心)
最新推荐文章于 2023-07-12 15:57:33 发布