1. 程式人生 > >資料結構課後習題 馬踏棋盤 c語言版

資料結構課後習題 馬踏棋盤 c語言版

馬踏棋盤 c語言版
輸入馬初始位置的座標。將初始位置進棧,經過一個while迴圈,取出符合條件的棧頂元素。
利用函式,找出棧頂元素周圍未被佔用的新位置,如果有,新位置入棧;否則彈出棧頂元素。再進行判斷,最後輸出。

將馬隨機放在國際象棋的8×8棋盤某個方格中,
馬按走棋規則進行移動。
要求每個方格只進入一次,走遍棋盤上全部64個方格。記錄其步驟
轉載的圖片
轉載的圖片

#include<stdio.h>
#include<stdlib.h>

#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10

typedef struct
//記錄座標位置 { int x; int y; }PosType; typedef struct //騎士跳步 { PosType seat; int di; //標記探索的下一個方向 }SElemType; typedef struct//棧的結構體 { SElemType *base; SElemType *top; int stacksize; }SqStack; int Init1[8][8] = { {0} };//此棋盤用以記錄所走過的路 int Init2[8][8] = { {2,3,4,4,4,4,3,2},//初始化棋盤,並標記每個位置所能跳的方向
{3,4,6,6,6,6,4,3},//例如當為2時,表示下一步只有兩個方向可跳 {4,6,8,8,8,8,6,4},//此棋盤用以記錄跳棋步驟 {4,6,8,8,8,8,6,4}, {4,6,8,8,8,8,6,4}, {4,6,8,8,8,8,6,4}, {3,4,6,6,6,6,4,3}, {2,3,4,4,4,4,3,2},}; int HTry1[8] = {-2, -1, 1, 2, 2, 1, -1, -2};//跳馬的下一步的x位置 int HTry2[8] = {1, 2, 2, 1, -1, -2, -2, -1};//跳馬的下一步的y位置
void MarkPrint(PosType pos);//此路不能通過,仍標記為0 PosType NextPos(PosType curpos,int x);//按順時針尋找下一個方向 void FootPrint(PosType &curpos,int surstep);//此路能過標記相應的步數 int Pass(PosType &curpos);//判斷此路是否能通過 int InitStack(SqStack &S);//初始化棧 void DestroyStack(SqStack &S);//銷燬棧 int StackEmpty(SqStack &S);//判斷棧是否為空 int Push(SqStack &S,SElemType e);//入棧 int Pop(SqStack &S,SElemType &e);//出棧 void print(int curstep);//列印路線 int main() { SqStack S; //棧的結構體 SElemType e; //標記探索的下一個方向 PosType Mincurpos,curpos,start; //記錄座標位置 int curstep; //記錄步數 InitStack(S); //初始化棧 printf("請輸入起始位置"); scanf("%d%d",&start.x,&start.y); //請輸入起始位置 curpos = start; //記錄初始座標位置 curstep = 1; //記錄座標順序位置 do{ if(Pass(curpos)) { //判斷此路是否能通過 FootPrint(curpos,curstep); //此路能過標記相應的步數 e.di = 0; //標記探索的下一個方向 e.seat= curpos; //記錄座標位置 Push(S,e); //入棧 if(curstep == 64) { //判斷棧滿 print(curstep); //列印路線 DestroyStack(S); //銷燬棧 return 1; } curpos = NextPos(curpos,e.di); //按順時針尋找下一個方向 curstep ++; //步數加一 } else { if(!StackEmpty(S)) { //判斷棧不為為空 Pop(S,e); //退棧 curstep --; //步數減一 while(e.di == 7 && !StackEmpty(S)) { MarkPrint(e.seat); //此路不能通過,仍標記為0 Pop(S,e); //退棧 curstep --; //步數減一 } if(e.di < 7) { Mincurpos = curpos; //Mincurpos記錄上次位置 e.di ++; //方向加一 curpos = NextPos(e.seat,e.di); //按順時針尋找下一個方向 while(Mincurpos.x == curpos.x && Mincurpos.y == curpos.y && e.di < 7) { e.di ++; //判斷此位置的下一個位置的八個方向的最小值是否相同,若相同則直接跳過 curpos = NextPos(e.seat,e.di); //按順時針尋找下一個方向 } Push(S,e); //出棧 curstep ++; //步數加一 } } } }while(!StackEmpty(S)); //棧不為空 DestroyStack(S); //銷燬棧 return 0; } void print(int curstep) //列印路線 { for(int i = 0; i < 8; i++) { for(int j = 0; j < 8; j++) printf("%3d",Init1[i][j]); //列印路線 printf("\n"); } printf("\n");printf("\n"); getchar(); } void MarkPrint(PosType pos) //此路不能通過,仍標記為0 { Init1[pos.x][pos.y] = 0; } PosType NextPos(PosType curpos,int x) //尋找下一個位置Init2[8][8]中最小的位置,並且此路沒有走過 { //尋找下一個位置Init2[8][8]中最小的位置,並且此路沒有走過 PosType MinCurpos,temp; MinCurpos.x = -1; MinCurpos.y = -1;//置此為最小的方向 for(;x < 8; x++) { temp.x = curpos.x + HTry1[x]; //跳馬的下一步的x位置 temp.y = curpos.y + HTry2[x]; //跳馬的下一步的y位置 if(temp.x < 0 || temp.x > 7 || temp.y < 0 || temp.y > 7 || Init1[temp.x][temp.y]) continue;//保證此位置在棋盤中 if(MinCurpos.x == -1 && MinCurpos.y == -1) //先找到下個位置第一個合法的位置 MinCurpos = temp; else if( Init2[MinCurpos.x][MinCurpos.y] > Init2[ temp.x][temp.y] )//比較找最小 MinCurpos= temp; } if(MinCurpos.x == -1 && MinCurpos.y == -1) //如果沒有下個位置,返回原來位置 return curpos; return MinCurpos; //如果有下個位置,返回位置 } void FootPrint(PosType &curpos,int curstep) //此路能過標記相應的步數 { Init1[curpos.x][curpos.y] = curstep; //此路能過標記相應的步數,將Init1存入步數 } int Pass(PosType &curpos) //判斷此路是否能通過 { if(!Init1[curpos.x][curpos.y]) //此路不能通過,return 1,否則返回 0 return 1; else return 0; } void DestroyStack(SqStack &S) //銷燬棧 { S.base = S.top; //base=top S.stacksize = 0; //size置為0 } int StackEmpty(SqStack &S) //判斷棧滿 { if(S.base == S.top) return 1; else return 0; } int InitStack(SqStack &S) //初始化棧 { S.base = (SElemType*)malloc(STACK_INIT_SIZE * sizeof(SElemType));//將s.base申請跳步型別100個空間 if(!S.base) return 0; S.top = S.base; S.stacksize = STACK_INIT_SIZE; //長度給100 return 1; } int Push(SqStack &S,SElemType e) //入棧 { if(S.top - S.base >= S.stacksize ) { //頂減底等於現在的棧中元素個數 S.base = (SElemType*)realloc(S.base,(STACK_INIT_SIZE+STACKINCREMENT )*sizeof(SElemType));//對malloc申請的記憶體進行大小的調整.調整為110 if(!S.base) return 0; S.top = S.base +S.stacksize; //頂為底加長度 S.stacksize += STACKINCREMENT; //長度加10 } *S.top++ = e; return 1; } int Pop(SqStack &S,SElemType &e) //出棧 { if(S.top == S.base) return 0; e = *--S.top; //e=*--S.top return 1; }