描述
国际象棋共有8行8列,64个单元格,无论将马放在棋盘的哪个单元格,都可以让马踏遍棋盘的每个单元格。要求编程实现马踏棋盘的过程,输出马在棋盘上走过的次序。
思路
- 使用循环逐个处理棋盘的64个单元格
- 将当前步数写入棋盘数组中,开始探测下一步该走的位置
- 分别测试八个方向,将可走的位置记录再next数组中
- 对可走位置进行再探测,找出每个位置的下一步可走步数,将步数最少的可走位置作为下一步的位置(每次都将步数最少的可走位置作为下一步的位置即贪心的体现)
- 循环2~4。
代码
#include<iostream>
#include<iomanip>
using namespace std;
struct coordinate{
int x;
int y;
};
int chessboard[8][8]={0};
int travel(coordinate start){
coordinate move[8]={{-2,1},{-1,2},{1,2},{2,1},{2,-1},{1,-2},{-1,-2},{-2,-1}};
coordinate next[8]={0};
int ways[8]={0};
coordinate curpos,tmp;
int count,count1,min,tmp1;
curpos=start;
chessboard[curpos.x][curpos.y]=1;//第一步为起始位置
for(int n=2;n<=64;n++){//循环2~64个位置
for(int m=0;m<8;m++){
ways[m]=0;//清空各位置的出路数
}
count1=0;
for(int j=0;j<8;j++){//试探8个方向
tmp.x=curpos.x+move[j].x;
tmp.y=curpos.y+move[j].y;
if(tmp.x<0||tmp.y<0||tmp.x>7||tmp.y>7) continue;
if(chessboard[tmp.x][tmp.y]==0){
next[count1]=tmp;//将可走的位置保存再next中
count1++;//该位置出口数量
}
}
count=count1;
if(count==0) return 0;
else if(count==1) min=0;
else{
for(int m=0;m<count;m++){
for(int j=0;j<8;j++){
tmp.x=next[m].x+move[j].x;
tmp.y=next[m].y+move[j].y;
if(tmp.x<0||tmp.y<0||tmp.x>7||tmp.y>7) continue;
if(chessboard[tmp.x][tmp.y]==0) ways[m]++;//可走位置的出路数量
}
}
tmp1=ways[0];
min=0;
for(int m=1;m<count;m++){//找出可走位置中出路数量最少的方向 min
if(ways[m]<tmp1){
tmp1=ways[m];
min=m;
}
}
}
curpos=next[min];//马跳到出路数量最少的位置
chessboard[curpos.x][curpos.y]=n;//记录马的步数
}
return 1;
}
int main(){
coordinate start;
cout<<"输入马的起始坐标位置:";
cin>>start.x>>start.y;
if(start.x<1||start.y<1||start.x>8||start.y>8){
cout<<"坐标输入错误,请重新输入!"<<endl;
exit(0);
}
start.x-=1;
start.y-=1;
if(travel(start)){
cout<<"马按以下顺序走:"<<endl;
for(int i=0;i<8;i++){
for(int j=0;j<8;j++){
cout<<setw(3)<<chessboard[i][j];
}
cout<<endl;
}
}else{
cout<<"遍历失败"<<endl;
}
return 0;
}