第十四届蓝桥杯国赛 C++ B 组 G 题——AB路线(AC)

目录

  • 1. AB路线
    • 1. 问题描述
    • 2. 输入格式
    • 3. 输出格式
    • 4. 样例输入
    • 5. 样例输出
    • 6. 样例说明
    • 7. 评测用例规模与约定
    • 8. 原题链接
  • 2. 解题思路
  • 3. AC_Code

1. AB路线

前置知识点:BFS (广度优先搜索)

1. 问题描述

有一个由 N × M N \times M N×M 个方格组成的迷宫,每个方格写有一个字母 A 或者 B。小蓝站在迷宫左上角的方格,目标是走到右下角的方格。他每一步可以移动到上下左右相邻的方格去。

由于特殊的原因,小蓝的路线必须先走 K K K 个 A 格子、再走 K K K 个 B 格子、再走 K K K 个 A 格子、再走 K K K 个 B 格子…如此反复交替。

请你计算小蓝最少需要走多少步,才能到达右下角方格? 注意路线经过的格子数不必一定是 K K K 的倍数,即最后一段 A 或 B 的格子可以不满 K K K 个。起点保证是 A 格子。

例如 K = 3 K = 3 K=3 时,以下 3 3 3 种路线是合法的:

AAA
AAAB
AAABBBAAABBB

以下 3 3 3 种路线不合法:

ABABAB
ABBBAAABBB
AAABBBBBBBAAA

2. 输入格式

第一行包含三个整数 N N N M M M K K K

以下 N N N 行,每行包含 M M M 个字符 ( A 或 B ),代表格子类型。

3. 输出格式

一个整数,代表最少步数。如果无法到达右下角,输出 − 1 −1 1

4. 样例输入

4 4 2 
AAAB 
ABAB 
BBAB 
BAAA

5. 样例输出

8

6. 样例说明

每一步方向如下:下右下右上右下下;路线序列:AABBAABBA。

7. 评测用例规模与约定

对于 20 % 20\% 20% 的数据, 1 ≤ N , M ≤ 4 1 \leq N,M \leq 4 1N,M4

对于另 20 % 20\% 20% 的数据, K = 1 K = 1 K=1

对于 100 % 100\% 100% 的数据, 1 ≤ N , M ≤ 1000 1 \leq N,M \leq 1000 1N,M1000 1 ≤ K ≤ 10 1 \leq K \leq 10 1K10

8. 原题链接

AB路线

2. 解题思路

在着手解决本问题之前,你需要熟悉基础的 BFS 搜索算法,具体内容可以参考这个链接:https://oi-wiki.org/graph/bfs/。

我们所熟知的 BFS 搜索模型常常是在一个迷宫中从左上角出发,目标是到达右下角,可以上下左右移动,但某些位置有陷阱无法通过,我们需要求的是最短到达时间。

这道题目的基本模型与我们熟悉的搜索模型大致相同,它们的共性包括:

  • 都是从左上角出发,目标是到达右下角。
  • 都可以在四个方向进行移动。
  • 每次移动的权值都为 1 1 1

因此,这道题很有可能可以使用 BFS 来解答。然而,我们还需要注意到它们的差异性:

  • 在常见的模型中,存在无法通过的陷阱,而在这道题目中,没有陷阱,这使得题目在这一点上甚至比常见的模型更简单。
  • 在常见的模型中,除了陷阱,可以随意移动,而在这道题目中,移动受到 A,B \text{A,B} A,B 格之间不能随意通行的限制。
  • 在常见的模型中,每个格子只能被访问一次,而在这道题目中,每个格子最多可以被访问 k k k 次。这一点非常重要。

接下来,我们将重点讨论最后这一点:

在常规的 BFS 算法中,我们会使用一个数组 s t i j st_{ij} stij 来标识某个位置是否已经被访问过。如果该值为 true,则表示该位置已经被访问过,不能再次访问;如果该值为 false,则表示该位置尚未被访问。这种做法是保证 BFS 算法复杂度的关键,因为每个位置最多只会被访问一次。

但在这道题目中,每个位置可能会被访问多次。因为题目规定 A A A 格只能到达 A A A 格,如果想从 A A A 格到达 B B B 格,必须在第 K K K 次访问 A A A 格时才能达到, B B B 格同理。

这就意味着,每个格子最多可能会被访问 K K K 次。假设某个格子 ( i , j ) (i,j) (i,j) 的字符为 A / B A/B A/B,到达它可能是连续走了 1 , 2 , ⋯ , K 1, 2, \cdots, K 1,2,,K A / B A/B A/B 格。

由于 K K K 的取值范围不大,我们可以考虑对 s t st st 数组进行扩展,定义 s t i , j , k st_{i,j,k} sti,j,k 表示连续走过 k k k A / B A/B A/B 格后是否能到达格子 ( i , j ) (i,j) (i,j),如果能,标记为 true,否则标记为 false。因此,对于同一个 k k k,我们最多只会访问一个格子一次。

在进行 BFS 转移过程中,我们需要根据当前连续步数 k k k 进行分类讨论:

  • 如果 k < K k<K k<K,我们只能从当前格子移动到相同字符的格子,然后 k k k 增加 1 1 1
  • 如果 k = = K k==K k==K,我们只能从当前格子移动到不同字符的格子,然后将 k k k 重置为 1 1 1

除此之外,所有步骤与普通的 BFS 算法相同,时间复杂度为 O ( n m k ) O(nmk) O(nmk)

3. AC_Code

  • C++
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int mod = 1000000007;
const int N = 1010;int n, m, k;
bool st[N][N][11];
int dx[] = {0, 1, 0, -1};
int dy[] = {-1, 0, 1, 0};int main()
{ios_base ::sync_with_stdio(false);cin.tie(0);cout.tie(0);cin >> n >> m >> k;vector<string> s(n);for (int i = 0; i < n; ++i){cin >> s[i];}queue<array<int, 3>> q;q.push({0, 0, 1});st[0][0][1] = true;int ans = 0;while (q.size()){int size = q.size();while (size--){auto p = q.front();q.pop();int x = p[0], y = p[1];if (x == n - 1 && y == m - 1){cout << ans << '\n';return 0;}if (p[2] == k){for (int i = 0; i < 4; ++i){int a = x + dx[i], b = y + dy[i];if (a >= 0 && a < n && b >= 0 && b < m && s[a][b] != s[x][y] && !st[a][b][1]){st[a][b][1] = true;q.push({a, b, 1});}}}else{for (int i = 0; i < 4; ++i){int a = x + dx[i], b = y + dy[i];if (a >= 0 && a < n && b >= 0 && b < m && s[a][b] == s[x][y] && !st[a][b][p[2] + 1]){st[a][b][p[2] + 1] = true;q.push({a, b, p[2] + 1});}}}}ans++;}cout << -1 << '\n';return 0;
}
  • Java
import java.util.*;public class Main {public static void main(String[] args) {Scanner input = new Scanner(System.in);int N = 1010;int n = input.nextInt();int m = input.nextInt();int k = input.nextInt();boolean[][][] st = new boolean[N][N][11];int[] dx = {0, 1, 0, -1};int[] dy = {-1, 0, 1, 0};String[] s = new String[n];for (int i = 0; i < n; ++i) {s[i] = input.next();}Queue<int[]> q = new LinkedList<>();q.add(new int[]{0, 0, 1});st[0][0][1] = true;int ans = 0;while (!q.isEmpty()) {int size = q.size();while (size-- > 0) {int[] p = q.poll();int x = p[0], y = p[1];if (x == n - 1 && y == m - 1) {System.out.println(ans);return;}if (p[2] == k) {for (int i = 0; i < 4; ++i) {int a = x + dx[i], b = y + dy[i];if (a >= 0 && a < n && b >= 0 && b < m && s[a].charAt(b) != s[x].charAt(y) && !st[a][b][1]) {st[a][b][1] = true;q.add(new int[]{a, b, 1});}}} else {for (int i = 0; i < 4; ++i) {int a = x + dx[i], b = y + dy[i];if (a >= 0 && a < n && b >= 0 && b < m && s[a].charAt(b) == s[x].charAt(y) && !st[a][b][p[2] + 1]) {st[a][b][p[2] + 1] = true;q.add(new int[]{a, b, p[2] + 1});}}}}ans++;}System.out.println(-1);}
}
  • Python
def slove():n, m, k = map(int, input().split())s = []for _ in range(n):s.append(input())q = []q.append([0, 0, 1])st = [[[False] * 11 for _ in range(m)] for _ in range(n)]st[0][0][1] = Trueans = 0dx = [0, 1, 0, -1]dy = [-1, 0, 1, 0]while q:size = len(q)while size > 0:p = q.pop(0)size -= 1x, y = p[0], p[1]if x == n - 1 and y == m - 1:print(ans)returnif p[2] == k:for i in range(4):a, b = x + dx[i], y + dy[i]if 0 <= a < n and 0 <= b < m and s[a][b] != s[x][y] and not st[a][b][1]:st[a][b][1] = Trueq.append([a, b, 1])else:for i in range(4):a, b = x + dx[i], y + dy[i]if 0 <= a < n and 0 <= b < m and s[a][b] == s[x][y] and not st[a][b][p[2] + 1]:st[a][b][p[2] + 1] = Trueq.append([a, b, p[2] + 1])ans += 1print(-1)slove()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/646104.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

flutter-相关个人记录

1、flutter 安卓打包打包报错 flutter build apk -v --no-tree-shake-icons 2、获取华为指纹证书命令 keytool -list -v -keystore ***.jks 3、IOS项目中私有方法查找隐藏文件中 1、cd 项目目录地址 2、grep -r xerbla. "xerbla"为需要查找的关键字 3…

【秒剪】如何一键恢复至素材原长?

Step1:点击下方【剪辑】 Step2:点击【时长截取】 Step3:点击【恢复至原长】 Step4:点击【恢复所有片段到原长】

推荐一个还可以的windows ssh工具

1.下载 https://github.com/kingToolbox/WindTerm/releases 2.解压 3.使用 上传 下载都很快 比cmd窗口好用 当然和finalshell有点像

JAVASE进阶(设计模式、设计原则)

目录 一、注解 内置注解:JAVA中已经定义好的注解。 元注解:修饰注解的注解。 自定义注解。 二、克隆 JAVA中对clone的实现? 浅克隆 深克隆 那么该如何做到深克隆呢? 三、常用设计模式 1、创建型模式 单例模式 工厂模式 工厂方法模式 抽象工厂模式 原型模式 一、注…

系统登录的时候的密码如何做到以加密的形式进行登录【java.security包下的api】工具类。

/** description: 将普通的publicKey转化得到一个RSAPublicKey* author: zkw* date: 2024/1/24 16:17* param: publicKey 普通的publicKey* return: RSAPublicKey 得到一个新的RSAPublicKey**/public static RSAPublicKey getPublicKey(String publicKey) throws NoSuchAlgorit…

oracle数据库插入或者更新判断是否存在记录的SQL

oracle数据库插入或者更新判断是否存在记录的SQL 1、插入的时候判断是否存在&#xff0c;若存在则忽略&#xff0c;若不存在则插入 写法① insert into student(id,name,sex) select 111,张三,女 from dual where not exists (select 1 from student where id 111)写法② …

vue中图片不显示问题 - vue中静态资源加载

文章目录 vue中图片不显示问题静态资源URL 转换规则webpack 静态资源处理 图片不显示问题问题描述解决办法1&#xff1a;使用require引入require is not defined 解决办法2&#xff1a;使用import引入解决办法3&#xff1a;将图片放进公共文件夹static或public vue中图片不显示…

代码随想录算法训练营第十四天|104.二叉树的最大深度,559.n叉树的最大深度,111.二叉树的最小深度,222.完全二叉树的节点个数

系列文章目录 代码随想录算法训练营第一天|数组理论基础&#xff0c;704. 二分查找&#xff0c;27. 移除元素 代码随想录算法训练营第二天|977.有序数组的平方 &#xff0c;209.长度最小的子数组 &#xff0c;59.螺旋矩阵II 代码随想录算法训练营第三天|链表理论基础&#xff…

Qt 鼠标按下移动释放事件

文章目录 1 通过自定义控件实现1.1 鼠标跟踪 2 鼠标事件移动标签 QEvent::MouseButtonPress ​ 鼠标按下时&#xff0c;触发该事件&#xff0c;它对应的子类是QMouseEvent QEvent::MouseMove ​ 鼠标移动时&#xff0c;触发该事件&#xff0c;它对应的子类是QMouseEvent QEv…

《解锁R统计分析:深度探索R Commander图形界面》

&#x1f482; 个人网站:【 海拥】【神级代码资源网站】【办公神器】&#x1f91f; 基于Web端打造的&#xff1a;&#x1f449;轻量化工具创作平台&#x1f485; 想寻找共同学习交流的小伙伴&#xff0c;请点击【全栈技术交流群】 在数据科学与大数据技术的浪潮中&#xff0c;R…

基于Java的学生宿舍门禁信息管理系统的设计与实现(源码+lw+部署文档+讲解等

目录 前言 详细视频演示 具体实现截图 技术栈 后端框架SpringBoot 前端框架Vue 持久层框架MyBaitsPlus 系统测试 系统测试目的 系统功能测试 系统测试结论 代码参考 数据库代码参考 源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、…

Cesium 常见配置

文章目录 常见配置1. 修改天空背景(skyBox)2. 去除版权信息3. 增加太阳光照效果4. 实现昼夜联动效果5. 显示帧数6. 增加太阳光照7. 大气层显示8. 开启地形深度检测9. 禁止相机进入地下10. 右键拖拽场景倾斜11. 关闭抗锯齿12. 鼠标操作惯性控制13. 自动调整分辨率14. 默认定位到…

记录:云计算学习日常之shell

一、初识shell 文件描述符与输出重定向&#xff1a; 在shell程式中&#xff0c;最常使用的FD(filedescriptor)有三个&#xff0c;分别是&#xff1a; 0&#xff1a;Standard Input(STDIN) 1&#xff1a;Standard Output(STDOUT) 2&#xff1a;Standard Error Output(STDER…

Linux 常见性能指标 -- 网络

本系列记录操作系统常见性能指标&#xff0c;写这个主要是记录也是回顾&#xff0c;笔记很长&#xff0c;拆分了几个部分&#xff0c;本篇记录 网络 的性能指标 日常最常见的问题就是 ping 能不能通&#xff0c;telnet 端口通不通&#xff0c;来判断网络是否正常。但是有些时候…

【数据结构】数据结构初识

前言&#xff1a; 数据结构是计算存储&#xff0c;组织数据的方式。数据结构是指相互间存在一种或多种特定关系的数据元素的集合。通常情况下&#xff0c;精心选择的数据结构可以带来更高的运行或者存储效率。数据结构往往同高效的检索算法和索引技术有关。 Data Structure Vi…

H.264数据解析

什么是H.264 H264 是 MPEG-4 标准所定义的最新编码格式&#xff0c;同时也是技术含量最高、代表最新技术水平的视频编码格式之一&#xff0c;标准写法应该是H.264 H264 视频格式是经过有损压缩的&#xff0c;但在技术上尽可能做的降低存储体积下获得较好图像质量和低带宽图像…

劳特巴赫的基础使用(二)

一、基本介绍 LAUTERBACH是世界领先的微处理器开发工具厂商&#xff0c;成立于1979年&#xff0c;总部位于德国慕尼黑。 JTAG Debugger由PowerDebug和Debug Cable组成。PowerDebug是通用控制模块&#xff0c;支持所有Cable&#xff0c;没有License。Debug Cable绑定License&a…

26、江科大stm32视频学习笔记——I2C读写W25Q64

一、W25Q64简介 1、W25Q64的内存空间结构: 一页256字节&#xff0c;4K(4096 字节)为一个扇区&#xff0c;16个扇区为1块&#xff0c;容量为8M字节&#xff0c;共有128个块&#xff0c;2048 个扇区。 2、W25Q64每页大小由256字节组成&#xff0c;每页的256字节用一次页编程指…

笔记:C++/C编程学习:使用nuget管理c++库的原理

如果要做一个应用程序&#xff0c;我们往往会用到很多第三方库&#xff0c;这时库包管理工具就很重要&#xff0c;如js/npm&#xff0c;c#/nuget&#xff0c;php/composer&#xff0c;jave/maven之类&#xff0c;但vc一直没一个很舒服的包管理工具。很多c第三方库对vc都非常不友…

保姆级:Palworld幻兽帕鲁32人服务器一键部署

创建幻兽帕鲁服务器1分钟部署教程&#xff0c;阿里云和腾讯云均推出幻兽帕鲁服务器服务器和部署教程&#xff0c;4核16G和4核32G配置可选&#xff0c;阿腾云atengyun.com分享1分钟自建幻兽帕鲁Palworld服务器教程&#xff1a; 幻兽帕鲁服务器创建教程 幻兽帕鲁服务器官方推荐…