鱼C论坛

 找回密码
 立即注册
查看: 1996|回复: 5

马踏棋盘问题,小甲鱼答案有一部分没看明白

[复制链接]
发表于 2020-5-13 17:08:29 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
马踏棋盘问题(又称骑士周游或骑士漫游问题)是算法设计的经典问题之一。
国际象棋的棋盘为8*8的方格棋盘,现将“马”放在任意指定的方格中,按照“马走日”的规则将“马”进行移动,要求每个方格只能进入一次,最终使得“马”走遍棋盘64个方格。



  1. #include <stdio.h>

  2. #define X 8
  3. #define Y 8

  4. int chess[X][Y];

  5. // 找到下一个可走的位置
  6. int next(int *px, int *py, int count)
  7. {
  8.         int x = *px;
  9.         int y = *py;

  10.         switch(count)
  11.         {
  12.         case 0:
  13.                 if (x+2<=X-1 && y-1>=0 && chess[x+2][y-1] == 0)
  14.                 {
  15.                         *px = x + 2;
  16.                         *py = y - 1;
  17.                         return 1;
  18.                 }
  19.                 break;
  20.         case 1:
  21.                 if (x+2<=X-1 && y+1<=Y-1 && chess[x+2][y+1] == 0)
  22.                 {
  23.                         *px = x + 2;
  24.                         *py = y + 1;
  25.                         return 1;
  26.                 }
  27.                 break;
  28.         case 2:
  29.                 if (x+1<=X-1 && y-2>=0 && chess[x+1][y-2] == 0)
  30.                 {
  31.                         *px = x + 1;
  32.                         *py = y - 2;
  33.                         return 1;
  34.                 }
  35.                 break;
  36.         case 3:
  37.                 if (x+1<=X-1 && y+2<=Y-1 && chess[x+1][y+2] == 0)
  38.                 {
  39.                         *px = x + 1;
  40.                         *py = y + 2;
  41.                         return 1;
  42.                 }
  43.                 break;
  44.         case 4:
  45.                 if (x-2>=0 && y-1>=0 && chess[x-2][y-1] == 0)
  46.                 {
  47.                         *px = x - 2;
  48.                         *py = y - 1;
  49.                         return 1;
  50.                 }
  51.                 break;
  52.         case 5:
  53.                 if (x-2>=0 && y+1<=Y-1 && chess[x-2][y+1] == 0)
  54.                 {
  55.                         *px = x - 2;
  56.                         *py = y + 1;
  57.                         return 1;
  58.                 }
  59.                 break;
  60.         case 6:
  61.                 if (x-1>=0 && y-2>=0 && chess[x-1][y-2] == 0)
  62.                 {
  63.                         *px = x - 1;
  64.                         *py = y - 2;
  65.                         return 1;
  66.                 }
  67.                 break;
  68.         case 7:
  69.                 if (x-1>=0 && y+2<=Y-1 && chess[x-1][y+2] == 0)
  70.                 {
  71.                         *px = x - 1;
  72.                         *py = y + 2;
  73.                         return 1;
  74.                 }
  75.                 break;
  76.         }

  77.         return 0;
  78. }

  79. int setHorse(int x, int y, int tag)
  80. {
  81.         int x1 = x, y1 = y, flag = 0, count = 0;

  82.         // tag记录轨迹
  83.         chess[x][y] = tag;
  84.         // 如果tag等于64退出程序
  85.         if (tag == X*Y)
  86.         {
  87.                 return 1;
  88.         }

  89.         // 如果可以走,那么flag为1
  90.         flag = next(&x1, &y1, count);
  91.         // 否则尝试其他路径
  92.         while (flag == 0 && count < 7)
  93.         {
  94.                 count += 1;
  95.                 flag = next(&x1, &y1, count);
  96.         }

  97.         // 递归进入下一个坐标
  98.         while (flag)
  99.         {
  100.                 // 返回1表示成功找到落脚点
  101.                 if (setHorse(x1, y1, tag+1))
  102.                 {
  103.                         return 1;
  104.                 }
  105.                 // 否则从上一步重新尝试
  106.                 x1 = x;
  107.                 y1 = y;
  108.                 count += 1;
  109.                 flag = next(&x1, &y1, count);
  110.                 while (flag == 0 && count < 7)
  111.                 {
  112.                         count += 1;
  113.                         flag = next(&x1, &y1, count);
  114.                 }
  115.         }

  116.         if (flag == 0)
  117.         {
  118.                 chess[x][y] = 0;
  119.         }

  120.         return 0;
  121. }

  122. int main(void)
  123. {
  124.         int i, j;

  125.         for (i = 0; i < X; i++)
  126.         {
  127.                 for (j = 0; j < Y; j++)
  128.                 {
  129.                         chess[i][j] = 0;
  130.                 }
  131.         }

  132.         // 讲道理,从 (2, 0) 坐标开始计算是比较容易出结果的
  133.         // 如果你比较有耐心,或 CPU 特别强劲,可以尝试计算其它坐标
  134.         if (setHorse(2, 0, 1))
  135.         {
  136.                 for (i = 0; i < X; i++)
  137.                 {
  138.                         for (j = 0; j < Y; j++)
  139.                         {
  140.                                 printf("%02d  ", chess[i][j]);
  141.                         }
  142.                         putchar('\n');
  143.                 }
  144.         }
  145.         else
  146.         {
  147.                 printf("可惜无解!\n");
  148.         }

  149.         return 0;
  150. }
复制代码


在setHOrse函数中while(flag) 迭代如果flag不为0则得到解,如果flag为0则退出循环,应该是无解,函数返回0,为什么中间要有一个
  1.         if (flag == 0)
  2.         {
  3.                 chess[x][y] = 0;
  4.         }
复制代码

并且当我删掉这段的时候,代码多次运行结果都为 无解? 这段代码的作用是什么
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2020-5-13 17:48:53 | 显示全部楼层

回帖奖励 +3 鱼币

领鱼币
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-5-13 17:52:44 | 显示全部楼层

回帖奖励 +3 鱼币

领鱼币x2
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-5-13 18:04:36 | 显示全部楼层

回帖奖励 +3 鱼币

正好缺鱼币
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-5-13 18:19:40 | 显示全部楼层
本帖最后由 赚小钱 于 2020-5-13 18:26 编辑

马走过的地方会被设置为1(二维数组上),flag 表示能否找到,下一个位置,如果 flag 表示,在当前位置没有一个可以走的下一个位置,那么应该回退,此时,即表示当前的路是错的,所以应该在二维数组将当前位置设置为0

PS: 算法属于回溯算法。
回溯算法的核心思想是:
选择一个起点出发,沿着某一条路,不断检测是否可用,
如果可用就继续这条路(即深度遍历)
当遇到某种情况,可以确定,这条路行不通的时候,(剪枝函数)
就回头(回溯),

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-5-13 20:23:02 From FishC Mobile | 显示全部楼层
帮顶。。。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-7-7 04:23

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表