每周一算法:双端队列广搜

题目链接

电路维修

题目描述

达达是来自异世界的魔女,她在漫无目的地四处漂流的时候,遇到了善良的少女翰翰,从而被收留在地球上。翰翰的家里有一辆飞行车。有一天飞行车的电路板突然出现了故障,导致无法启动。

电路板的整体结构是一个 R R R C C C列的网格( R , C ≤ 500 R,C≤500 R,C500),如下图所示:
在这里插入图片描述
每个格点都是电线的接点,每个格子都包含一个电子元件。电子元件的主要部分是一个可旋转的、连接一条对角线上的两个接点的短电缆。在旋转之后,它就可以连接另一条对角线的两个接点。电路板左上角的接点接入直流电源,右下角的接点接入飞行车的发动装置。

达达发现因为某些元件的方向不小心发生了改变,电路板可能处于断路的状态。她准备通过计算,旋转最少数量的元件,使电源与发动装置通过若干条短缆相连。不过,电路的规模实在是太大了,达达并不擅长编程,希望你能够帮她解决这个问题。

注意:只能走斜向的线段,水平和竖直线段不能走。

输入描述

输入文件包含多组测试数据。

第一行包含一个整数 T T T,表示测试数据的数目。对于每组测试数据,第一行包含正整数 R R R C C C,表示电路板的行数和列数。

之后 R R R行,每行 C C C个字符,字符是/\中的一个,表示标准件的方向。

输出描述

对于每组测试数据,在单独的一行输出一个正整数,表示所需的缩小旋转次数。
如果无论怎样都不能使得电源和发动机之间连通,输出NO SOLUTION

样例输入

1
3 5
\\/\\
\\///
/\\\\

样例输出

1

算法思想

根据题目描述,每个格子都包含一个电子元件,主要部分是一个可旋转的、连接一条对角线上的两个接点的短电缆,如下图所示。

在这里插入图片描述
旋转一个电子元件的代价为 1 1 1,问最少旋转几个元件,使起点与终点通过若干条短缆相连。

连通性

由于只能走斜向的线段,水平和竖直线段不能走,所以选择左上角的接点作为起点,只能连接如下图(左)绿色的接点,二下图(右)红色的接点是无法连通的。
在这里插入图片描述
通过分析发现,如果将起点设为左上角,那么能够连接的点(绿色),其行列值的和为偶数。因此,是否使得电源和发动机之间连通,需要判断 ( n + m ) (n+m) (n+m)是否为偶数。

最小代价

如果电子元件的最初状态为下图所示,那么从 A − > B A->B A>B的代价为 0 0 0,不需要旋转;而从 C − > D C->D C>D的代价为 1 1 1,需要旋转 1 1 1次。
在这里插入图片描述
因此,求旋转最少数量的元件,使电源与发动装置通过若干条短缆相连,可以转换为求从起点到终点,当连接的两点之间代价为 0 0 0 1 1 1时的最短路。

双端队列广搜

对于只包含边权 0 0 0 1 1 1的最短路问题,可以使用双端队列广搜求解。与普通的BFS不同的是:

  • 如果扩展到的新节点边权为 0 0 0时,需要把新节点插入队列的头部。

这样处理满足BFS的两个性质:

  • 两段性:队列中同时存在的所有点到起点的距离差值最多是1。
  • 单调性:队列分成两段,前面一定是小的

因此可以使用BFS求最短路。

代码实现

#include <iostream>
#include <cstring>
#include <queue>
using namespace std;typedef pair<int, int> PII;
const int N = 505;
char g[N][N];
int n, m, st[N][N], dis[N][N];//元件的偏移值:左上,右上,右下,左下
int dx[4] = {-1, -1, 1, 1}, dy[4] = {-1, 1, 1, -1};
//连接元件的电缆方向在字符数组位置的偏移值:左上,右上,右下,左下
int ix[4] = {-1, -1, 0, 0}, iy[4] = {-1, 0, 0, -1};
//不需要旋转的连接方向,左上,右上,右下,左下
char c[] = "\\/\\/"; //"\/\/"
int bfs()
{memset(st, 0, sizeof st);memset(dis, 0x3f, sizeof dis);deque<PII> q;dis[0][0] = 0; q.push_back({0, 0});while(q.size()){PII t = q.front(); q.pop_front(); //从队头出队int x = t.first, y = t.second;if(st[x][y]) continue;st[x][y] = true;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) continue;int ai = x + ix[i], bi = y + iy[i];//元件方向在数组中的位置int w = g[ai][bi] != c[i]; //如果不是正确的连接方向,需要旋转,边权为1if(dis[a][b] > dis[x][y] + w){dis[a][b] = dis[x][y] + w;if(w == 1) q.push_back({a, b}); //边权为1加入队尾else q.push_front({a, b}); //边权为0加入队头}}}return dis[n][m];
}
int main()
{int T;cin >> T;while(T --){cin >> n >> m;for(int i = 0; i < n; i ++) cin >> g[i];if(n + m & 1) {puts("NO SOLUTION");continue;}int t = bfs();if(t == 0x3f3f3f3f) puts("NO SOLUTION");else cout << t << '\n';}
}

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

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

相关文章

【学习心得】Python调用JS的三种常用方法

在做JS逆向的时候&#xff0c;一种情况是直接用Python代码复现JS代码的功能&#xff0c;达成目的。但很多时候这种方法有明显的缺点&#xff0c;那就是一旦JS代码逻辑发生了更改&#xff0c;你就得重写Python的代码逻辑非常不便。于是第二种情况就出现了&#xff0c;我直接得到…

vue项目从后端下载文件显示进度条或者loading

//API接口 export const exportDownload (params?: Object, peCallback?: Function) > {return new Promise((resolve, reject) > {axios({method: get,url: ,headers: {access_token: ${getToken()},},responseType: blob,params,onDownloadProgress: (pe) > {peC…

10分钟SkyWalking与SpringBoot融合并整合到Linux中

1.依赖配置 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>2.2.0.RELEASE</version></dependency><dependency><groupId>org.springframe…

IP源防攻击IPSG(IP Source Guard)

IP源防攻击IPSG&#xff08;IP Source Guard&#xff09;是一种基于二层接口的源IP地址过滤技术&#xff0c;它能够防止恶意主机伪造合法主机的IP地址来仿冒合法主机&#xff0c;还能确保非授权主机不能通过自己指定IP地址的方式来访问网络或攻击网络。 2.1 IPSG基本原理 绑定…

深入探讨Java中的OutputStreamWriter类

咦咦咦&#xff0c;各位小可爱&#xff0c;我是你们的好伙伴——bug菌&#xff0c;今天又来给大家普及Java SE相关知识点了&#xff0c;别躲起来啊&#xff0c;听我讲干货还不快点赞&#xff0c;赞多了我就有动力讲得更嗨啦&#xff01;所以呀&#xff0c;养成先点赞后阅读的好…

人工智能、机器学习和生成式人工智能之间有什么区别?

文 | BFT机器人 在这个数字的智能时代&#xff0c;大家对人工智能、机器学习和生成式人工智能这些名词字眼很熟悉&#xff0c;有些人或许对它们还有一些了解&#xff0c;但是当他们一起出现的时候&#xff0c;大家能够区别它们是什么意思吗&#xff1f;今天小编将带你们详细解…

【GPU驱动开发】- AST简介

前言 不必害怕未知&#xff0c;无需恐惧犯错&#xff0c;做一个Creator&#xff01; AST&#xff0c;抽象语法树&#xff0c;是一种包含丰富语义信息的格式&#xff0c;其中包括类型、表达式树和符号等。 TranslationUnitDecl&#xff1a;该类表示一个输入源文件 ASTContext&…

一般情况下,硬件中使用Repeating Sequence出现波形很奇怪就是数据的周期频率和mcu运行的频率不一致导致的

一般情况下&#xff0c;出现波形很奇怪就是数据的周期频率和mcu运行的频率不一致导致的 把timer values 修改为0 1就好了&#xff0c;如果是0&#xff0c;0.1就不行&#xff0c;不会有下面的波形

spring boot 集成科大讯飞星火认知大模型

首先到官网https://console.xfyun.cn/services/aidoc申请key 一、安装依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance&…

基于java SSM springboot+redis网上水果超市商城设计和实现以及文档

基于java SSM springbootredis网上水果超市商城设计和实现以及文档 博主介绍&#xff1a;多年java开发经验&#xff0c;专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 央顺技术团队 Java毕设项目精品实战案例《1000套》 欢迎点赞 收藏 …

Linux——进程控制(一)进程的创建与退出

目录 一、进程创建 1.写时拷贝 2.创建多个进程 二、进程终止 1.main函数的返回值 2.bash中的$? 3.自定义退出码 4.C语言的错误码 5.错误码与退出码的区别 6.代码异常终止 7.exit函数 8.总结 一、进程创建 在之前&#xff0c;我们学过linux中的非常重要的函数——…

苍穹外卖知识点总结(一)

简介 技术选型 展示项目中使用到的技术框架和中间件。 用户层&#xff1a;node.js Vue.js ElementUI 微信小程序 apache echarts 网关层&#xff1a;nginx 应用层&#xff1a;Spring Boot Spring MVC Spring Task httpclie…

Java毕业设计 基于SSM SpringBoot vue购物比价网站

Java毕业设计 基于SSM SpringBoot vue购物比价网站 SSM vue 购物比价网站 功能介绍 首页 图片轮播 商品 商品分类 商品详情 评论 收藏 商品攻略 商品信息 公告栏 在线反馈 登录 注册 个人中心 我的收藏 后台管理 登录 注册商品户 个人中心 修改密码 个人信息 商品户管理 用户…

Excel2LaTeX插件的使用、LaTeX表格

目录 一、下载Excel2Latex 二、使用Excel2Latex 1、将Excel2LaTeX文件添加到加载项 2、导出LaTex的表格数据 3、注意事项 1&#xff09;生成的latex表格断断续续问题 2&#xff09;改变线形的粗细 3&#xff09;表格太大&#xff0c;需要缩小到适应大小 4&#xff09;…

ETL是什么

一、ETL概念 ETL&#xff0c;是英文Extract-Transform-Load的缩写&#xff0c;用来描述将数据从来源端经过抽取&#xff08;extract&#xff09;、转换&#xff08;transform&#xff09;、加载&#xff08;load&#xff09;至目的端的过程。ETL一词较常用在数据仓库&#xff…

qsort函数(任意类型排序)

void qsort(void base, size_t num, size_t size, int (*compar)(const void*p1, const void*p2))排序函数&#xff0c;可以排序各种类型的函数 四个参数&#xff1a; void qsort( void base&#xff0c;&#xff1a;base指向数组的第一个元素 size_t num,&#xff1a;base…

Gitlab: 私有化部署

目录 1. 说明 2. 资源要求 3. 安装 4. 配置实践 4.1 服务器 4.2 人员与项目 4.2 部署准备 4.2.1 访问变量及用户账号设置 4.2.2 Runner设置 4.2.3 要点 5. 应用项目 CI/CD 6. 参考 1. 说明 gitlab是一个强大且免费的代码管理/部署工具&#xff0c;能统一集成代码仓…

ubuntu基础操作(1)-个人笔记

搜狗输入法Linux官网-首页搜狗输入法for linux—支持全拼、简拼、模糊音、云输入、皮肤、中英混输https://pinyin.sogou.com/linux 1.关闭sudo密码&#xff1a; 终端&#xff08;ctrl alt t&#xff09;输入 sudo visudo 打开visudo 找到 %sudo ALL(ALL:ALL) ALL 这一行…

视频和音频使用ffmpeg进行合并和分离(MP4)

1.下载ffmpeg 官网地址&#xff1a;https://ffmpeg.org/download.html 2.配置环境变量 此电脑右键点击 属性 - 高级系统配置 -高级 -环境变量 - 系统变量 path 新增 文件的bin路径 3.验证配置成功 ffmpeg -version 返回版本信息说明配置成功4.执行合并 ffmpeg -i 武家坡20…

DTD、XML阐述、XML的两种文档类型约束和DTD的使用

目录 ​编辑 一、DTD 什么是DTD&#xff1f; 为什么要使用 DTD&#xff1f; 内部 DTD 声明 具有内部 DTD 的 XML 文档 外部 DTD 声明 引用外部 DTD 的 XML 文档 二、XML 什么是XML&#xff1f; XML 不执行任何操作 XML 和 HTML 之间的区别 XML 不使用预定义的标记…