zoukankan      html  css  js  c++  java
  • 国际象棋棋盘上马的遍历问题

    【问题描述】 在一个具有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 }
  • 相关阅读:
    忍者X3 链接统计工具
    新版淘宝客广告生成器发布
    今天编写了淘宝客生成工具
    淘宝客appkey做了大范围的取消、查封
    DiscuzX3.0 发布插件
    网易博客营销插件
    [转]iOS 应用程序的生命周期
    [转]Xcode的快捷键及代码格式化
    OC——关于KVO
    OC——关于KVC
  • 原文地址:https://www.cnblogs.com/wally/p/2743037.html
Copyright © 2011-2022 走看看