C++实现骑士走棋盘算法

 更新时间:2021年07月23日 10:10:56   作者:老樊Lu码  
这篇文章主要为大家详细介绍了C++实现骑士走棋盘算法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了C++实现骑士走棋盘算法的具体代码,供大家参考,具体内容如下

1.问题描述

骑士旅游Knight tour在十八世纪初倍受数学家与拼图迷的注意,它什么时候被提出已不可考,骑士的走法为西洋 棋的走法,骑士可以由任一个位置出发,它要如何走完所有的位置。

2.基本思路

骑士的走法,基本上可以用递回来解决,但是纯粹的递回在维度大时相当没有效率,一个聪明的解法由J.CWarnsdorff 在1823年提出, 简单地说,先将最难的位置走完,接下来的路就宽广了,骑士所想要的下一步,为下一不再 选 择时,所能走的步数最少的一步。使用这个方法,在不使用递回的情况下,可以有较高的机率找出走法(找不到走 的机率也是有的)

3.代码实现

#include <stdio.h>
 
int pos[8][8] = { 0 };
 
int travel(int, int);
 
int travel(int x, int y) {
 int i, j, k, l, m;
 int tmpX, tmpY;
 int count, min, tmp;
 
 //骑士可走的八个方向(顺时针)
 int ktmoveX[8] = { 1, 2, 2, 1, -1, -2, -2, -1 };
 int ktmoveY[8] = { -2, -1, 1, 2, 2, 1, -1, -2 };
 
 //测试下一步坐标
 int nextX[8] = { 0 };
 int nextY[8] = { 0 };
 
 //记录每个方向的出路的个数
 int exists[8] = { 0 };
 
 //起始用1标记位置
 i = x;
 j = y;
 pos[i][j] = 1;
 
 //遍历棋盘
 for (m = 2; m <= 64; m++) {
  //初始化八个方向出口个数
  for (l = 0; l < 8; l++) {
   exists[l] = 0;
  }
  l = 0; //计算可走方向
 
      //试探八个方向
  for (k = 0; k < 8; k++) {
   tmpX = i + ktmoveX[k];
   tmpY = j + ktmoveY[k];
   //边界 跳过
   if (tmpX < 0 || tmpY < 0 || tmpX>7 || tmpY>7) {
    continue;
   }
   //可走 记录
   if (pos[tmpX][tmpY] == 0) {
    nextX[l] = tmpX;
    nextY[l] = tmpY;
    l++;    //可走方向加1
   }
  }
  count = l;
  //无路可走 返回
  if (count == 0) {
   return 0;
   //一个方向可走 标记
  }
  else if (count == 1) {
   min = 0;
   //找出下个位置出路个数
  }
  else {
   for (l = 0; l < count; l++) {
    for (k = 0; k < 8; k++) {
     tmpX = nextX[l] + ktmoveX[k];
     tmpY = nextY[l] + ktmoveY[k];
     if (tmpX < 0 || tmpY < 0 || tmpX>7 || tmpY>7) {
      continue;
     }
     if (pos[tmpX][tmpY] == 0) {
      exists[l]++;
     }
    }
   }
   //找出下个位置出路最少的方向
   min = 0;
   tmp = exists[0];
   for (l = 0; l < count; l++) {
    if (exists[l] < tmp) {
     tmp = exists[l];
     min = l;
    }
   }
  }
  //用序号标记走过的位置
  i = nextX[min];
  j = nextY[min];
  pos[i][j] = m;
 }
 return 1;
}
 
int main()
{
 int i, j, startX, startY;
 while (1)
 {
  printf("输入起始点:");
  scanf("%d%d", &startX, &startY);
  if (travel(startX, startY)) {
   printf("游历完成!\n");
  }
  else {
   printf("游历失败!\n");
  }
  for (i = 0; i < 8; i++) {
   for (j = 0; j < 8; j++) {
    printf("%2d ", pos[i][j]);
   }
   printf("\n");
  }
  printf("\n");
 }
 
 return 0;
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • 牛顿迭代法求多项式在1.5附近的值2*x的3次幂--4x平方+3*x-6=0的实现代码

    牛顿迭代法求多项式在1.5附近的值2*x的3次幂--4x平方+3*x-6=0的实现代码

    以下代码是使用了牛顿迭代法求多项式在1.5附近的值 2*x的3次幂 - 4x的平方 + 3*x -6=0的实例。需要的朋友参考下吧
    2013-05-05
  • 记逆向小白的第一次vbsedit 9爆破及内存补丁制作过程

    记逆向小白的第一次vbsedit 9爆破及内存补丁制作过程

    这篇文章主要介绍了记逆向小白的第一次vbsedit 9爆破及内存补丁制作过程,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-04-04
  • c++回调之利用函数指针示例

    c++回调之利用函数指针示例

    这篇文章主要介绍了c++利用函数指针示例,需要的朋友可以参考下
    2014-04-04
  • C++中关于互斥量的全面认知

    C++中关于互斥量的全面认知

    线程的主要优势在于,能够通过全局变量来共享信息。不过,这种便捷的共享是有代价的:必须确保多个线程不会同时修改同一变量,或者某一线程不会读取正由其他线程修改的变量。为了防止出现线程某甲试图访 问一共享变量时,线程某乙正在对其进行修改。引入了互斥量
    2022-05-05
  • C语言入门篇--理解地址及内存

    C语言入门篇--理解地址及内存

    本篇文章是基础篇,适合c语言刚入门的朋友,本文主要介绍了c语言的内存及地址,帮助大家快速入门c语言的世界,更好的理解c语言
    2021-08-08
  • C++ cin不同状态详细讲解

    C++ cin不同状态详细讲解

    cin是C++编程语言中的标准输入流对象,即istream类的对象。cin主要用于从标准输入读取数据,这里的标准输入,指的是终端的键盘。此外,cout是流的对象,即ostream类的对象,cerr是标准错误输出流的对象,也是ostream类的对象
    2022-10-10
  • C++11并发编程关于原子操作atomic的代码示例

    C++11并发编程关于原子操作atomic的代码示例

    今天小编就为大家分享一篇关于C++11并发编程关于原子操作atomic的代码示例,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2018-12-12
  • C++实现二叉树非递归遍历算法详解

    C++实现二叉树非递归遍历算法详解

    在C++中,二叉树非递归遍历是一种常用的算法,可避免递归过程中的系统开销和栈溢出问题。非递归遍历算法利用栈数据结构实现,可以实现前序、中序和后序遍历,是C++程序员必备技能之一
    2023-04-04
  • C语言学生成绩管理系统源代码

    C语言学生成绩管理系统源代码

    这篇文章主要为大家详细介绍了C语言学生成绩管理系统源代码,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-03-03
  • c++递归解数独方法示例

    c++递归解数独方法示例

    这篇文章主要介绍了c++递归解数独方法示例,需要的朋友可以参考下
    2014-03-03

最新评论