國際象棋棋盤上馬的遍歷問題


【問題描述】 在一個具有8×8個方格的國際象棋盤上,從棋盤的任何一個方格 開始,讓馬按照允許的走步規則(L形走法)走遍所有方格,每個方格 至少並且只准走過一次。試設計一個算法實現這個有趣的問題。

【基本要求】 將馬隨機放在棋盤的某個方格中,根據J.C.Warnsdorff提出的規則 來進行遍歷。編制非遞歸程序,求出馬的行走路線,輸出所走各步的 位置。

【測試數據】 由用戶自行指定一個馬的起始位置(i, j), 0≤i, j≤7。

【實現提示】 (1)棋盤用 8×8的二維數組表示。 (2)當馬位於位置(i, j)時,可以走到下列8個位置之一:(i-2, j+1), (i-1, j+2), (i+1, j+2), (i+2, j+1), (i+2, j-1), (i+1, j-2), (i-1, j-2), (i-2, j-1)。 但是,如果(i,j)靠近棋盤的邊緣,上述有些位置可能超出棋盤范圍, 成為不允許的位置。8個可能位置的位移量可以用兩個一維數組imove[8] 和jmove[8]來存儲。

(3)根據J.C.Warnsdorff提出的規則來設計算法。該規則是在所有 可走步的(尚未走過的)方格中,馬只能走向這樣一個方格:從該方格 出發,馬可走步的方格數為最少,如果可走步的方格數相等,則從馬的 當前位置來看,方向序號小的優先。 (4)采用Warnsdorff規則在大多數情況下能夠實現遍歷,但並不能 確保成功。

【選作內容】 (1)按求出的行走路線,將數字1, 2, 3,…,64依次填入一個8×8的方 陣,輸出之。 (2)在不考慮Warnsdorff規則的情況下,求出從某一起點出發的多 條以至全部行走路線。

允許我直接貼代碼了

  1 #include"queue.h"
  2 struct point {
  3     int x;//馬的x方向
  4     int y;//馬的y方向
  5 };
  6 
  7 typedef struct Queue{
  8     struct point  queue[MaxQueueSize];
  9     int front;//頭指針
 10     int rear;//尾指針
 11     int tag;//設置標記位
 12 }SeqCQueue;
 13 
 14 //初始化隊列操作
 15 void QueueInitiate(SeqCQueue *Q){
 16     Q->front=0;
 17     Q->rear=0;
 18     Q->tag=0;
 19 }
 20 
 21 //判斷隊列是否為空
 22 int QueueNotEmpty(SeqCQueue Q){
 23     if(Q.front==Q.rear&&Q.tag==0)
 24         return 0;
 25     else 
 26         return 1;
 27 }
 28 
 29 //入隊操作
 30 void  QueueAppend(SeqCQueue *Q,point  x){
 31     if(Q->tag==1&&Q->front==Q->rear){
 32         printf("隊列已滿,無法插入!\n");
 33     }else {
 34         Q->queue[Q->rear]=x;
 35         Q->rear=(Q->rear+1)%MaxQueueSize;
 36         Q->tag=1;
 37     }
 38 }
 39 
 40 //出隊操作
 41 void QueuePop(SeqCQueue *Q,point  *d){
 42     if(Q->tag==0&&Q->front==Q->rear){
 43         printf("隊列已空,無元素可以出隊列!\n");
 44     }else {
 45         *d=Q->queue[Q->front];
 46         Q->front=(Q->front+1)%MaxQueueSize;
 47         Q->tag=0;
 48     }
 49 }
 50 
 51 #include<stdio.h>
 52 #include<string.h>
 53 #define MaxQueueSize 64
 54 #include "queue.h"
 55 #define MAXN 8
 56 
 57 SeqCQueue Q;
 58 
 59 int m,n;
 60 int step;//記錄馬走的步數
 61 int map[MAXN][MAXN];//8*8的國際象棋棋盤
 62 int dir[8][2]={{-2,-1},{-2,1},{-1,-2},{-1,2},{1,-2},{1,2},{2,-1},{2,1}};//馬理論上所能走全部的位置
 63 
 64 
 65 //求出該位置的馬所能走的步數
 66 int _step(int x,int y){
 67     int i,xi,yi;
 68     int count=0;
 69     for( i=0;i<8;i++){
 70         xi=x+dir[i][0];
 71         yi=y+dir[i][1];
 72         //邊界條件以及!map[xi][yi]表示未走過的位置
 73         if(xi>=0&&xi<=MAXN-1&&yi>=0&&yi<=MAXN-1&&!map[xi][yi])
 74             count++;
 75     }
 76     return count;
 77 }
 78 
 79 int BFS(point s)
 80 {
 81     int i,x,y,temp;
 82     QueueInitiate(&Q);//初始化隊列
 83     QueueAppend(&Q,s);//入隊操作
 84     point hd ;
 85     int flag=0 ;
 86     //當隊列非空時,進行廣度優先搜索
 87     while(QueueNotEmpty(Q))
 88     {
 89         QueuePop(&Q,&hd);//出隊列
 90         map[hd.x][hd.y]=step++;//標記該位置已走過
 91         printf("%d,%d\n",hd.x,hd.y);//輸出走過的位置
 92         int minstep=10;//初始的最小步數
 93         int flag=0;//標記
 94         //8個方向進行搜索
 95         for( i=0;i<8;i++){
 96             x=hd.x+dir[i][0];
 97             y=hd.y+dir[i][1];
 98             if(x>=0&& 
 99                 x<=MAXN-1&&y>=0&&y<=MAXN-1&&!map[x][y]){
100                 //如果小於當前的最小步數,則讓隊列元素出隊列,並讓當前的元素入隊列
101                 if(_step(x,y)<minstep){
102                     minstep=_step(x,y) ;
103                     point t ,th ;
104                     t.x=x,t.y=y ;
105                     if(flag) QueuePop(&Q,&th) ;//如果是第一次的話,就不用出隊列了;
106                     QueueAppend(&Q,t) ;
107                     flag=1;
108                 }
109             }
110         }
111     }
112     return step-1;
113 }
114 
115 int main()
116 {
117     while(scanf("%d%d",&m,&n)!=EOF){
118         //判斷起始位置是否合法
119         if(m<0||m>7||n<0||n>7){
120             printf("起始位置不合法!\n\n");
121         }else {
122             printf("\n");
123             memset(map,0,sizeof(map));//將8*8的棋盤全部置為0
124             point start;
125             start.x=m,start.y=n;
126             step=1;
127             step=BFS(start);
128             //按求出的行走路線,將數字1, 2, 3,…,64依次填入一個8×8的方陣,輸出
129             for(int i=0;i<MAXN;i++){
130                 for(int j=0;j<MAXN;j++){
131                     printf("%-3d",map[i][j]);
132                 }
133                 printf("\n");
134             }
135             printf("step=%d.\n",step);
136             printf("\n");
137         }
138     }
139     return 0;
140 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM