首页 > 编程语言 >骑士游历问题(马踏棋盘)解析(c++)

骑士游历问题(马踏棋盘)解析(c++)

时间:2022-11-21 18:09:09浏览次数:33  
标签:遍历 return int 马踏 dfs else c++ cal 棋盘


骑士游历问题:在国际棋盘上使一个骑士遍历所有的格子一遍且仅一遍,对于任意给定的顶点,输出一条符合上述要求的路径

解题思路:

这是一道经典的遍历问题(DFS),由于题目要求遍历全部,那么肯定要做标记,因此立马想到DFS深度优先算法。具体思路如下:
①了解国际象棋以及国际象棋骑士的走法

国际象棋和中国象棋,大同小异,毕竟中国象棋是老祖先。国际象棋棋子放在格子中,中国象棋放在点上,且国际象棋有64个格子。国际象棋的骑士和中国象棋的马功能相当,都可以走八个方位。走法是走“日”字,或英文字母大写的“L”形:即先向左(或右)走1格,再向上(或下)走2格;或先向左(或右)走2格,再向上(或下)走1格。与中国象棋的馬不同,国际象棋的马可以跳过路上的其他棋子,不受拐脚的限制。

解题需要我们可以把格子抽象成一个点,那么国际象棋的骑士走法就是一个日字

骑士游历问题(马踏棋盘)解析(c++)_初始化

骑士游历问题(马踏棋盘)解析(c++)_初始化_02

②设置标记

初始化数组,让每个元素初始化为0,并且初始化一个记录骑士遍历次数的cal也为0
int cal = 0; //统计走的顺序
//初始化为0
int chress[8][8] =
{
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0
};

③判断是否超界和是否被访问

bool ifOut(int x, int y)  //判断是否出界
{
if (x >= 0 && x <= 7 && y >= 0 && y <= 7)
return false;
else
return true;
}
bool ifVisited(int x, int y) //判断是否被访问
{
if (chress[x][y] != 0)
return true;
else
return false;
}

④递归主体

void dfs(int x,int y)
{
if (cal == 64) //如果遍历完则退出棋盘一共64个位置
return;
if (!ifVisited(x, y) && !ifOut(x, y)) //如果没有被访问且没有出界 则访问
{
cal++;
chress[x][y] = cal; //做标记
dfs(x + 2, y + 1); //骑士走法有八个方位,故八个 方位都遍历
dfs(x - 2, y - 1); //八个递归的顺序可以改,顺序不一样,结果不一样
dfs(x + 2, y - 1);
dfs(x - 2, y + 1);
dfs(x - 1, y - 2);
dfs(x + 1, y - 2);
dfs(x + 1, y + 2);
dfs(x - 1, y + 2);
return;
}
else //else其中包括已经被访问了,和没有被访问且在界外的
return;
}
⑤总代码如下(编译器vs2013)
#include"stdafx.h"
#include<iostream>
#include<iomanip>
using namespace std;
int cal = 0; //统计走的顺序
//棋盘初始化为0做标记
int chress[8][8] =
{
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0
};

bool ifOut(int x, int y) //判断是否出界
{
if (x >= 0 && x <= 7 && y >= 0 && y <= 7)
return false;
else
return true;
}
bool ifVisited(int x, int y) //判断是否已经被访问
{
if (chress[x][y] != 0)
return true;
else
return false;
}
void dfs(int x,int y)
{
if (cal == 64) //如果遍历完则退出棋盘一共64个位置
return;
if (!ifVisited(x, y) && !ifOut(x, y)) //如果没有被访问且没有出界 则访问
{
cal++;
chress[x][y] = cal; //做标记
dfs(x + 2, y + 1); //骑士走法有八个方位,故八个 方位都遍历
dfs(x - 2, y - 1); //八个递归的顺序可以改,顺序不一样,结果不一样
dfs(x + 2, y - 1);
dfs(x - 2, y + 1);
dfs(x - 1, y - 2);
dfs(x + 1, y - 2);
dfs(x + 1, y + 2);
dfs(x - 1, y + 2);
return;
}
else //出界了则退出return
return;



}
int main()
{
int x, y;
cout << "请输入骑士初始的位置:";
while (1)
{
cin >> x >> y; //输入坐标
if (x > 7 || x<0 || y> 7 || y < 0)
cout << "初始位置输入错误请重新输入" << endl;
else
break;
}
dfs(x,y);
for (int i = 0; i < 8; i++) //输出打印测试
{
for (int j = 0; j < 8; j++)
cout << setw(2)<<chress[i][j]<<" ";
cout << endl;
}
return 0;
}

⑥测试截图:

骑士游历问题(马踏棋盘)解析(c++)_马踏棋盘问题_03


骑士游历问题(马踏棋盘)解析(c++)_李阡殇_04


骑士游历问题(马踏棋盘)解析(c++)_马踏棋盘问题_05


骑士游历问题(马踏棋盘)解析(c++)_马踏棋盘问题_06


标签:遍历,return,int,马踏,dfs,else,c++,cal,棋盘
From: https://blog.51cto.com/u_13796931/5869580

相关文章

  • pthread_cancel在C++中使用的坑
    问题现象在项目中,某些情况下需要动态地创建和销毁线程。Linux系统下,一般用到的是posix线程库pthread提供的一系列API。此篇讲述的便是在C++11中使用posix线程库pthread_ca......
  • 使用cmake编译c++源代码
    构建项目的背景:现在的主流都是编写一个cmakelist.txt,通过cmake去构建一个makefile,再make这个makefile生成可执行文件或者动态库静态库。 法1:1.新建一个CMakeLists.tx......
  • C++中的Struct和Class异同
    C++中为了和语言兼容,保留了C语言中的struct关键字,并且进行了适当扩充.C语言=>struct只是包含成员变量,但不包括成员函数C++中=>struct和class非常类似,既可以包括成员......
  • VS 2022创建ATL组件 (C++)
    步骤如下: 1、新建ATL项目 打开VisualStudio2022新建ATL项目2、添加接口类、实现接口方法.  添加一个新的ATL对象。右键MyComTest项目→添加→新建项→ATL→......
  • C++多线程
    c++多线程多线程其实非常简单多线程是多任务处理的一种特殊形式,多任务处理允许让电脑同时运行两个或两个以上的程序。一般情况下,两种类型的多任务处理:基于进程和基于线程......
  • [排序算法] 基数排序 (C++)
    基数排序解释基数排序基数排序RadixSort是一种非基于比较的排序算法。在基数排序中,和计数排序、桶排序的思想类似,我们要再次用到桶这个东西。......
  • C++初阶(vector容器+模拟实现)
    迭代器四种迭代器容器类名::iterator迭代器名;//正向迭代器容器类名::const_iterator迭代器名;//常量正向迭代器,const修饰,只能用于读取容器内的元素,不能改变其值容......
  • 用C/C++开发工业软件适合吗?
    用C/C++开发工业软件最适合的了,这是因为C/C++是仅次于汇编语言的最底层程序开发语言;同时工业软件最大的特征就是专业性强、复杂度高,需要相当深的专业知识、经验、科研基础,并......
  • C++ using 编译指令与名称冲突
    using编译指令:它由名称空间名和它前面的关键字usingnamespace组成,它使名称空间中的所有名称都可用,而不需要使用作用域解析运算符。在全局声明区域中使用using编译指......
  • effectiveC++1、2
    条款01视C++为一个语言联邦​ 在学习c++高效编程时会出现“所有的适当用法都有例外”的情况,解决的方法是:不把c++当作一门语言,而是将其视为以下四门主要次语言组成的联邦......