news 2026/2/16 8:07:30

【例8.3】最少步数(信息学奥赛一本通- P1330)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【例8.3】最少步数(信息学奥赛一本通- P1330)

【题目描述】

在各种棋中,棋子的走法总是一定的,如中国象棋中马走“日”。有一位小学生就想如果马能有两种走法将增加其趣味性,因此,他规定马既能按“日”走,也能如象一样走“田”字。他的同桌平时喜欢下围棋,知道这件事后觉得很有趣,就想试一试,在一个(100×100)的围棋盘上任选两点A、B,A点放上黑子,B点放上白子,代表两匹马。棋子可以按“日”字走,也可以按“田”字走,俩人一个走黑马,一个走白马。谁用最少的步数走到左上角坐标为(1,1)的点时,谁获胜。现在他请你帮忙,给你A、B两点的坐标,想知道两个位置到(1,1)点可能的最少步数。

【输入】

A、B两点的坐标。

【输出】

最少步数。

【输入样例】

12 16 18 10

【输出样例】

8 9

1. 题目背景

在经典的搜索问题中,我们经常遇到“马走日”的最短路问题。但如果有位小学生突发奇想,规定棋子不仅能走“日”,还能像象一样走“田”字,这道题该怎么解呢?

题目大意

  • 地图的围棋盘。

  • 移动规则

    1. :中国象棋马的走法(例如坐标偏移)。

    2. :向四个斜角方向飞两格(即坐标偏移)。

  • 目标:给定起点A和B,分别求它们走到左上角(1,1)的最少步数。

2. 算法分析:广度优先搜索 (BFS)

这是一个典型的无权图最短路径问题。

在一个网格图中,求从起点到终点的最少步数,且每一步的代价都是1,BFS(广度优先搜索)是最优解。

核心难点:方向数组的构建

普通的马只有 8 个跳跃方向,但这道题增加了“田”字走法。我们需要正确定义 12 个方向的偏移量。

  1. “日”字走法 (8种)

    • (+1, +2), (+1, -2), (-1, +2), (-1, -2)

    • (+2, +1), (+2, -1), (-2, +1), (-2, -1)

  2. “田”字走法 (4种)

    • (+2, +2), (+2, -2), (-2, +2), (-2, -2)

实现细节

  1. 状态记录 (vis数组)

    • vis[x][y]既用来标记是否访问过,也用来记录步数。

    • 技巧:为了区分“未访问(0)”和“起点的步数(0)”,我们将起点的vis设为 1。最终输出结果时,由vis[1][1]-1还原真实步数。

  2. 局部变量优化

    • queue定义在bfs函数内部,确保每次调用函数时队列都是空的,避免多组数据互相污染。

  3. 提前退出

    • 一旦从队列中取出的点坐标为(1,1),说明最短路已找到,直接return,减少不必要的计算。

3. 完整代码

#include <iostream> #include <queue> #include <cstring> using namespace std; int vis[110][110];//记录走到每个点需要的步数 //方向数组:前8个是“日”,后4个是“田” //日: (±1, ±2), (±2, ±1) //田: (±2, ±2) int dx[12]={2,-2,2,-2,1,-1,1,-1,2,2,-2,-2}; int dy[12]={1,1,-1,-1,2,2,-2,-2,2,-2,2,-2}; struct node{ int x,y; }; queue<node> q; void bfs(int x,int y){//马现在的位置 queue<node> q; node tmp; tmp.x=x; tmp.y=y; q.push(tmp);//队首入队 while(!q.empty()){ tmp=q.front();//访问队首 q.pop();//队首出队 //如果已经从队列里取出了(1,1),说明最短路已经找到了 //注意:这里是在取出时判断,或者在入队时判断都可以 if(tmp.x==1&&tmp.y==1) return; for(int i=0;i<12;i++){ int nx=tmp.x+dx[i]; int ny=tmp.y+dy[i]; // 边界判断+判断是否已经走过 if(nx>=1&&nx<=100&&ny>=1&&ny<=100&&vis[nx][ny]==0){ vis[nx][ny]=vis[tmp.x][tmp.y]+1; q.push({nx,ny}); } } } } int main(){ int xa,ya,xb,yb; cin>>xa>>ya>>xb>>yb; vis[xa][ya]=1; bfs(xa,ya); cout<<vis[1][1]-1<<endl; memset(vis,0,sizeof(vis)); vis[xb][yb]=1; bfs(xb,yb); cout<<vis[1][1]-1<<endl; }

4. 总结

  1. 多组数据重置

    本题虽然是一次运行求两个点,但相当于两组数据。在计算完A点后,必须使用memset(vis,0,sizeof(vis))清空状态数组,否则计算B点时会受到A点遗留数据的干扰。

  2. 队列作用域

    如果将queue定义为全局变量,记得在每次bfs开始前清空它(或者像我代码中一样定义为局部变量)。

  3. 方向数组

    写12个方向时容易手误写错正负号,建议按规律分组写(如代码中的注释所示),并在草稿纸上简单验证。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/14 3:31:12

大模型必收藏:文本表示全解析(从分词到词向量技术详解)

本文系统介绍了NLP中的文本表示技术&#xff0c;包括分词方法&#xff08;词级、字符级、子词级&#xff09;和词表示技术&#xff08;One-hot编码、Word2Vec、上下文相关词表示&#xff09;。详细阐述了英文和中文分词策略&#xff0c;以及如何使用Word2Vec生成语义化词向量&a…

作者头像 李华
网站建设 2026/2/14 12:09:22

SAP拒绝调整续约折扣政策应对云业务增速放缓

尽管云业务预期低于预期并导致其五年来最大的股价跌幅&#xff0c;SAP仍拒绝改变其续约折扣策略。在企业软件供应商市值动荡的一周内&#xff0c;这家欧洲ERP巨头在1月29日预测其云业务积压订单增长将出现轻微下降后&#xff0c;市值暴跌22%。该公司公布的2025日历年度营收为36…

作者头像 李华
网站建设 2026/2/15 16:14:06

科研数据AI分析工具,AI应用架构师的数据分析新手段

科研数据AI分析工具:AI应用架构师的数据分析新手段 关键词:科研数据AI分析、AI应用架构师、数据分析工具、机器学习模型、数据预处理、可视化工具、架构设计、多模态数据融合 摘要:在大数据与人工智能飞速发展的今天,科研领域正经历着从传统分析向智能分析的深刻变革。科研…

作者头像 李华
网站建设 2026/2/14 19:25:51

【游戏推荐】心门守卫 (Gatekeeper)免安装中文版

类型&#xff1a; 动作, 小游戏, 肉鸽 链接&#xff1a;https://pan.quark.cn/s/c39a046197d9 游戏简介 一股强大的恶势力偷走了寰宇之心。你必须勇闯一个未知宇宙并重新夺回失窃的心脏。但是你的任务并没有表面上的那么简单&#xff1a;寰宇之心被藏在了一座量子牢笼之中&am…

作者头像 李华
网站建设 2026/2/16 5:19:43

外包干了5天,技术明显退步

我是一名本科生&#xff0c;自2019年起&#xff0c;我便在南京某软件公司担任功能测试的工作。这份工作虽然稳定&#xff0c;但日复一日的重复性工作让我逐渐陷入了舒适区&#xff0c;失去了前进的动力。两年的时光匆匆流逝&#xff0c;我却在原地踏步&#xff0c;技术没有丝毫…

作者头像 李华
网站建设 2026/2/16 1:54:58

能源化工领域,SpringMVC如何支持百M级别大文件的上传下载监控?

大文件传输解决方案技术方案 项目需求分析 根据贵司提出的需求&#xff0c;我整理出以下关键点&#xff1a; 超大文件传输能力&#xff08;50G-100G级别&#xff09;完整的文件夹传输及层级结构保留高稳定性断点续传&#xff08;跨会话保持&#xff09;数据安全要求&#xf…

作者头像 李华