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

题目链接

电路维修

题目描述

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

电路板的整体结构是一个 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.hqwc.cn/news/503373.html

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

相关文章

计算以e为底1+x的自然对数 即ln(1+x) math.log1p(x)

【小白从小学Python、C、Java】 【计算机等考500强证书考研】 【Python-数据分析】 计算以e为底 1x的自然对数 即ln(1x) math.log1p(x) [太阳]选择题 请问执行以下程序的运行结果是&#xff1a; import math print("【执行】math.log1p(0)") print (math.log1p(0)) …

Python3零基础教程之字符串专题进阶

大家好&#xff0c;我是千与编程&#xff0c;上一期我们讲解了Python3编程语言中的数组与列表专题。这一期我们讲解了字符串专题初阶。 在 Python3 的字符串专题进阶教程中&#xff0c;我们将深入探讨更高级的字符串操作技巧&#xff0c;包括字符串切片、替换、去除空白、分割与…

FaceBook获取广告数据

1、访问 广告管理工具 确认自己登陆的账号下面能看到户。 ​ 2、使用 图谱Api探索工具 生成用户短期口令 ​ 3、get请求(或者浏览器直接打开)访问&#xff1a; https://graph.facebook.com/v19.0/me?fieldsid,name, email&access_token{上一步生成的口令} ​ 4、短期…

GIT概述及安装

文章目录 01.GIT概述内容小结 02.GIT相关概念(掌握)目标内容小结 03.GIT下载与安装目标内容 01.GIT概述 内容 Git是目前世界上最先进的分布式文件版本控制系统&#xff08;没有之一&#xff09; 版本控制 所谓的版本控制就是将一组文件的改动记录下来&#xff0c;形成版本历史…

2023年12月CCF-GESP编程能力等级认证Scratch图形化编程三级真题解析

一、单选题(共15题,共30分) 第1题 现代计算机是指电子计算机,它所基于的是( )体系结构。 A:艾伦图灵 B:冯诺依曼 C:阿塔纳索夫 D:埃克特-莫克利 答案:B 第2题 默认小猫角色,执行下列程序,舞台上会看到? ( ) A: B: C: D: 答案:C

Python并发编程:多线程-GIL全局解释器锁

一 引子 在Cpython解释器中&#xff0c;同一个进程下开启的多线程&#xff0c;同一时刻只能有一个线程执行&#xff0c;无法利用多核优势首先&#xff1a;需要明确的一点是GIL并不是Python的特性&#xff0c;它是在实现Python解析器(CPython)时所引入的一个概念。就好比c是一套…

C语言 for 循环语句的基本格式是什么?

一、问题 for 循环语句在C语⾔中是最为常见的循环语句&#xff0c;其功能强⼤&#xff0c;⽽且⽤法灵活&#xff0c;那么它的基本格式是什么呢&#xff1f; 二、解答 for 语句的⼀般形式为&#xff1a; for(表达式1;表达式2;表达3&#xff09;语句; 每条 for 语句包含三个⽤分…

0基础跨考计算机|408保姆级全年计划

我也是零基础备考408&#xff01; 虽说是计算机专业&#xff0c;但是本科一学期学十几门,真的期末考试完脑子里什么都不进的...基本都是考前一周发疯学完水过考试...&#x1f605; 想要零基础跨考可以直接从王道开始&#xff01;跟教材一点一点啃完全没必要&#x1f978; 现在…

理解python3中的回调函数

百度百科说&#xff1a;回调函数就是一个通过函数指针调用的函数。如果你把函数的指针&#xff08;地址&#xff09;作为参数传递给另一个函数&#xff0c;当这个指针被用来调用其所指向的函数时&#xff0c;我们就说这是回调函数。回调函数不是由该函数的实现方直接调用&#…

协议(网络协议)

HTTP/HTTPS 协议 HTTP 实际上是个缩写&#xff0c;英文全称是&#xff1a;Hyper Text Transfer Protocol &#xff08;超文本传输协议&#xff09;。 最常用的网页&#xff08;也叫web页&#xff09;就是一种超文本的具体表现形式。HTTPS &#xff08;全称&#xff1a;Hyper …

速看!深夜悄悄分享一个电力优化代码集合包!

代码集合包如下&#xff1a; 主从博弈的智能小区定价策略及电动汽车调度策略 碳交易机制下的综合能源优化调度 两阶段鲁棒优化算法的微网多电源容量配置 冷热电多能互补综合能源系统优化调度 考虑预测不确定性的综合能源调度优化 考虑柔性负荷的综合能源系统低碳经济优化调度 考…

回归预测 | Matlab实现BiTCN基于双向时间卷积网络的数据回归预测

回归预测 | Matlab实现BiTCN基于双向时间卷积网络的数据回归预测 目录 回归预测 | Matlab实现BiTCN基于双向时间卷积网络的数据回归预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab实现BiTCN基于双向时间卷积网络的数据回归预测&#xff08;完整源码和数据&a…