骑士走棋盘
#define SIZE 8
int possible(int board[][SIZE],int nexti[],int nextj[],int x,int y);
int min_direction(int board[][SIZE],int nexti[],int nextj[],int count);
bool travel(int board[][SIZE],int x,int y)
{
int nexti[SIZE] = {0};
int nextj[SIZE] = {0};//记录下一跳的位置信息
int i = x;
int j = y;
board[i][j] = 1;//标记第一个点访问
int MAX = SIZE*SIZE;
int count = 0;//
for(int m=2;m<=MAX;m++)
{
count=possible(board,nexti,nextj,i,j);//得到可能的下一跳数目 ,其中nexti[],nextj[]中记录了下一跳的跳法
if(count==0)
return false; //无可走方向,遍历失败
int min_Direction=min_direction(board,nexti,nextj,count);//在多个可能方向中查找下一跳方向最少的方向
i=nexti[min_Direction]; //下一跳位置坐标
j=nextj[min_Direction];
board[i][j]=m; //当前位置为第m次走的位置
}
return true;
}
int possible(int board[][SIZE],int nexti[],int nextj[],int x,int y)
{
int mvi[SIZE]={-2,-1,1,2,2,1,-1,-2}; //下一跳可能的八个方向(x坐标y坐标)
int mvj[SIZE]={1,2,2,1,-1,-2,-2,-1};
int count=0;
for(int i=0;i<SIZE;++i) //依次遍历8个方向
{
int tmpx=x+mvi[i];
int tmpy=y+mvj[i]; //计算移动后的位置信息
if(tmpx<0||tmpy<0||tmpx>SIZE-1||tmpy>SIZE-1)
continue; //越界,不是可行方向
if(board[tmpx][tmpy]==0) //未走过,找到一个可能方向
{
nexti[count]=tmpx;
nextj[count]=tmpy;
count++;
}
}
return count; //返回可能的下一跳的数目
}
void printBoard(int board[][SIZE],FILE *fp_out)
{
for(int i=0;i<SIZE;i++)
{
for(int j=0;j<SIZE;j++)
{
cout<<board[i][j]<<" ";
fprintf(fp_out,"%d ",board[i][j]);
}
fprintf(fp_out,"%s","\n");
cout<<endl;
}
fprintf(fp_out,"%s","\n \n");
}
//计算可能下一跳中下一跳中数目最少的跳法
int min_direction(int board[][SIZE],int nexti[],int nextj[],int count)
{
int mvx[SIZE]={-2,-1,1,2,2,1,-1,-2};
int mvy[SIZE]={1,2,2,1,-1,-2,-2,-1};
int exist[SIZE]={0}; //记录该方向的下一跳方向的数目
int min_direction=-1; //初始化最小方向数的方向
if(count==1)min_direction=0; //只有一个可行方向
else
{
for(int i=0;i<count;++i) //在所有可行方向中遍历
for(int j=0;j<SIZE;++j) //计算每一个方向下一跳的数目
{
int tmpx=nexti[i]+mvx[j];
int tmpy=nextj[i]+mvy[j];
if(tmpx<0||tmpy<0||tmpx>SIZE-1||tmpy>SIZE-1)//判断是否越界
continue;
if(board[tmpx][tmpy]==0)
exist[i]++;
}
int min=exist[0]; //取其中最小数目的方向
min_direction=0;
//选出最小的跳法
for(int i=1;i<count;++i)
if(exist[i]<min)
{
min=exist[i];
min_direction=i;
}
}//end else
return min_direction;
}
int main()
{
int start_u,start_v;//起始坐标
int board[SIZE][SIZE];
FILE *fp_out = NULL;
while(scanf("%d%d",&start_u,&start_v)!=EOF)
{
fp_out = fopen("F:\\Student\\result2.4.txt","a+");
for(int i=0;i<SIZE;i++)
for(int j=0;j<SIZE;j++)
board[i][j] = 0;//初始化没有访问过
if(travel(board,start_u,start_v))
{
cout<<"遍历成功!"<<endl;
}
else cout<<"遍历失败!"<<endl;
printBoard(board,fp_out);
fclose(fp_out);
}
return 0;
}