[C语言][数据结构]马踏棋盘问题
Posted Billy Miracle
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[C语言][数据结构]马踏棋盘问题相关的知识,希望对你有一定的参考价值。
将马放入国际象棋8×8棋盘的制定的某个方格中,马按走棋规则进行移动,要求每个方格只进入一次,走遍棋盘上全部64个方格。求出马的行走路线,并按求出的行走路线将数字1,2,…,64依次填入一个8×8的方阵并输出。 特别规定,马的8个探索方向如下图所示的1至8的顺序探索。
输入格式:
输入两个整数 m 和n(空格间隔),表示起始行列号。
输出格式:
以矩阵形式将8×8棋盘中的路线输出。 每个数自占两个字符的宽度(不足两位时,右对齐),每个数后面空一格。
输入样例1:
1 1
//结尾无空行
输出样例1:
1 38 55 34 3 36 19 22
54 47 2 37 20 23 4 17
39 56 33 46 35 18 21 10
48 53 40 57 24 11 16 5
59 32 45 52 41 26 9 12
44 49 58 25 62 15 6 27
31 60 51 42 29 8 13 64
50 43 30 61 14 63 28 7
//结尾无空行
输入样例2:
4 1
//结尾无空行
输出样例2:
38 49 56 3 30 41 14 5
57 2 39 42 55 4 31 12
50 37 48 29 40 13 6 15
1 58 43 54 27 32 11 20
36 51 28 47 62 21 16 7
59 44 53 26 33 10 19 22
52 35 46 61 24 63 8 17
45 60 25 34 9 18 23 64
//结尾无空行
思路与代码:
定义马位置(x,y)坐标的结构体:
typedef struct {
int x;
int y;
} Coordinate;
定义棋盘:
int chessboard[8][8]={0};
定义查找方向结构体:
因为规定了查找方向的顺序,所以查找方向也要按照规定顺序:
Coordinate move[8] = {{-2,1},{-1,2},{1,2},{2,1},{2,-1},{1,-2},{-1,-2},{-2,-1}};
定义栈内点信息的结构体:
typedef struct {
int ord;
//顺序(第几部)
Coordinate seat;
//位置
int di;
//查找方向
} SElemType;
定义栈:
typedef struct {
SElemType *base;
SElemType *top;
int stacksize;
} SqStack;
初始化栈:
int InitStack(SqStack *s1) {
s1->base=(SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType));
if(!s1->base) {
exit(1);
}
s1->top=s1->base;
s1->stacksize = STACK_INIT_SIZE;
return 1;
}
可以看到:base保存了栈数组的首地址,top保存的是栈顶元素的下一位的地址,stacksize保存的是栈的长度。
出栈pop逻辑较为简单:
只需要
SElemType Pop(SqStack*s,SElemType m) {
m = *(--s->top);
//top位置移动,移到被弹出的栈顶元素位置
//顺势输出
return m;
}
入栈逻辑:
int Push(SqStack *s1,SElemType m) {
if(s1->top-s1->base>=s1->stacksize) {
//如果栈满,则增加栈长度
s1->base=(SElemType *)realloc(s1->base,(s1->stacksize+n)*sizeof(SElemType));
if(!s1->base)
exit (1);
s1->top=s1->base+s1->stacksize;
s1->stacksize+=n;
}
//直接入栈
*(s1->top++)=m;
return 1;
}
计算下一个位置:
传入当前点与搜索方向
Coordinate NextPos(Coordinate s,int i) {
s.x = s.x+move[i].x;
s.y = s.y+move[i].y;
return(s);
}
判断点是否有效(在棋盘内),是则返回1:
int Pass(Coordinate s) {
if(chessboard[s.x][s.y]==0&&(s.x<=7)&&(s.x>=0)&&(s.y<=7)&&(s.y>=0)) {
return 1;
} else {
return 0;
}
}
主函数:
int main() {
int i,j;
Coordinate start;
scanf("%d %d", &start.x, &start.y);
start.x -= 1;
start.y -= 1;
//核心函数
knight(start);
for (i = 0; i < 8; i++) {
for(j = 0; j < 8; j++) {
printf("%2d ", chessboard[i][j]);
}
printf("\\n");
}
return 0;
}
核心函数:
void knight(Coordinate start) {
int curstep = 0;
SqStack S;
SElemType e;
Coordinate curpos = start;
InitStack(&S);
do {
if(Pass(curpos)) {
//curpos在棋盘内
curstep++;
chessboard[curpos.x][curpos.y] = curstep;
e.seat = curpos;
e.ord = curstep;
e.di = 0;
//初始化点信息
Push(&S, e);
//入栈
if(curstep == 64) {
//找到64个即结束
break;
} else {
//否则找下一个点
curpos=NextPos(curpos, e.di);}
} else {
//不在棋盘内
if(!StackEmpty(&S)) {
Pop(&S, e);
if(e.di == 7) {
chessboard[e.seat.x][e.seat.y]=0;
}
while(e.di == 7 && !StackEmpty(&S)) {
e = Pop(&S, e);
//八个方向都找过,则说明这步走不到结束,那么出栈,将棋盘重置,需要更换上一步的走法
if(e.di == 7) {
chessboard[e.seat.x][e.seat.y] = 0;
}
curstep = e.ord;
}
if(e.di < 7) {
//八个方向没找满,继续找下一个方向
e.di++;
Push(&S, e);
curpos = NextPos(e.seat, e.di);
}
}
}
} while(!StackEmpty(&S));
//非空一直走
}
以上是关于[C语言][数据结构]马踏棋盘问题的主要内容,如果未能解决你的问题,请参考以下文章