???牛客周赛55:虫洞操纵者
题目描述
\,\,\,\,\,\,\,\,\,\,你需要在一个可以上下左右移动的 n×nn\times nn×n 棋盘上解开一个迷宫:棋盘四周都是墙;每个方格要么是可以通过的空方格 ′0′\sf '0'′0′ ,要么是不可通过的墙方格 ′1′\sf '1'′1′ ;你可以沿着空方格通行;你已经被传送到了迷宫的左上角(第 111 行第 111 列的位置),你知道终点位于迷宫右下角(第 nnn 行第 nnn 列的位置)。
\,\,\,\,\,\,\,\,\,\,别人都不知道的是,你是一个虫洞大师,当你所在的位置能同时看到左右两侧或上下两侧最近的那两面相对的墙时,你可以在这两面墙上开启虫洞,靠近后从一侧进入,穿越它到达另一侧。
\,\,\,\,\,\,\,\,\,\,现在,你准备好以最短的步数离开迷宫了吗!
输入描述:
\,\,\,\,\,\,\,\,\,\,第一行输入一个整数 n(2≤n≤103)n\left(2\le n \le 10^3\right)n(2≤n≤103) 代表迷宫的大小。
\,\,\,\,\,\,\,\,\,\,此后 nnn 行,第 iii 行输入 nnn 个整数 ai,1,ai,2,…,ai,n(0≤ai,j≤1)a_{i,1},a_{i,2},\dots,a_{i,n} \left(0\le a_{i,j}\le 1\right)ai,1,ai,2,…,ai,n(0≤ai,j≤1) 代表迷宫中第 iii 行第 jjj 列这个格子中的情况,其中 000 代表空方格,111 代表墙方格。保证起点和终点不为墙壁。
输出描述:
\,\,\,\,\,\,\,\,\,\,在一行上输出一个整数,代表离开迷宫需要的最短步数,如果无论如何都无法离开迷宫,则直接输出 −1-1−1 。
示例1
输入
复制5 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0
5 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0
输出
复制3
3
说明
\,\,\,\,\,\,\,\,\,\,该样例示意图如下图所示。全部墙壁的位置都使用粗黑线标注。先从 (1,1)(1,1)(1,1) 向右移动一步走到 (1,2)(1,2)(1,2) ,此时可以开启一个虫洞(使用紫色箭头标注),向上移动一步到达 (5,2)(5,2)(5,2) ;此时可以开启第二个虫洞(使用红色箭头标注),向左移动一步到达 (5,5)(5,5)(5,5) 。
\,\,\,\,\,\,\,\,\,\,
\,\,\,\,\,\,\,\,\,\,注意,在该样例中,不能直接从 (1,1)(1,1)(1,1) 开启虫洞(使用黑色箭头标注)到达 (1,5)(1,5)(1,5) ,因为 (1,4)(1,4)(1,4) 存在两面墙遮挡了视线;不能直接从 (4,3)(4,3)(4,3) 开启虫洞(使用绿色箭头标注)到达 (1,3)(1,3)(1,3) ,因为这两面墙不是相对的。
\,\,\,\,\,\,\,\,\,\,
示例2
输入
复制5 0 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
5 0 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
输出
复制5
5
说明
\,\,\,\,\,\,\,\,\,\,
示例3
输入
复制2 0 1 1 0
2 0 1 1 0
输出
复制-1
-1
做法
#include<bits/stdc++.h>
using namespace std;int n;
int a[1010][1010];
int vis[1010][1010];
int dx[]={0,0,1,-1};
int dy[]={1,-1,0,0};struct ty{int x,y;int dis;
};int sign;
queue<ty> q;void bfs(){q.push({1,1,0});while(!q.empty()){ty tmp=q.front();q.pop();if(tmp.x==n&&tmp.y==n){cout<<tmp.dis;sign=1;return ;}if(vis[tmp.x][tmp.y]) continue;vis[tmp.x][tmp.y]=1;for(int i=0;i<4;i++){int xx=dx[i]+tmp.x;int yy=tmp.y+dy[i];if(a[xx][yy]==0){//墙壁//反方向搜,直到碰到墙壁while(a[xx-dx[i]][yy-dy[i]]) xx=xx-dx[i],yy=yy-dy[i];}if(vis[xx][yy]) continue;q.push({xx,yy,tmp.dis+1});}}
}int main(){scanf("%d",&n);for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){cin>>a[i][j];a[i][j]^=1;//异或一下的话路变成1,墙壁变成0,四周的墙壁也是0}}bfs();if(sign==0) cout<<-1;}
我的做法错了,不知道为啥,和题解的做法不一样的就是我四周的墙壁单独处理了。然后穿墙的时候找穿越的位置也不是一个个暴力找,而是用了二分函数找。但是只过了20%,实在是找不到为什么。
#include<bits/stdc++.h>
using namespace std;int n;
int a[1010][1010];
vector<int> h[1010],l[1010];
int vis[1010][1010];
int vis1[1010][1010][4];
int dx[]={0,0,1,-1};//右左下上
int dy[]={1,-1,0,0};struct ty{int x,y;int dis;
};int sign;
queue<ty> q;void bfs(){q.push({1,1,0});while(!q.empty()){ty tmp=q.front();q.pop();vis[tmp.x][tmp.y]=1;if(tmp.x==n&&tmp.y==n){cout<<tmp.dis;sign=1;return ;}for(int i=0;i<4;i++){int xx=dx[i]+tmp.x;int yy=tmp.y+dy[i];//四周墙壁if(yy<1){//左if(h[xx].size()==0&&!vis[xx][n]) q.push({xx,n,tmp.dis+1});else if(h[xx].size()!=0&&!vis[xx][h[xx][0]-1])q.push({xx,h[xx][0]-1,tmp.dis+1});continue;}if(xx<1){//上if(l[yy].size()==0&&!vis[n][yy]) q.push({n,yy,tmp.dis+1});else if(l[yy].size()!=0&&!vis[l[yy][0]-1][yy]) q.push({l[yy][0]-1,yy,tmp.dis+1});continue;}if(yy>n){//右if(h[xx].size()==0&&!vis[xx][1]) q.push({xx,1,tmp.dis+1});else if(h[xx].size()!=0&&!vis[xx][h[xx][h[xx].size()-1]+1]) q.push({xx,h[xx][h[xx].size()-1]+1,tmp.dis+1});continue;}if(xx>n){//下if(l[yy].size()==0&&!vis[1][yy]) q.push({1,yy,tmp.dis+1});else if(l[yy].size()!=0&&!vis[l[yy][l[yy].size()-1]+1][yy]) q.push({l[yy][l[yy].size()-1]+1,yy,tmp.dis+1});continue;}if(a[xx][yy]==1){//墙壁if(vis1[xx][yy][i]) continue;vis1[xx][yy][i]=1;if(i==0) {//右if(h[xx].size()==1) q.push({xx,1,tmp.dis+1});else{int id=lower_bound(h[xx].begin(),h[xx].end(),yy)-h[xx].begin()-1;if(id!=-1) q.push({xx,h[xx][id]+1,tmp.dis+1});else q.push({xx,1,tmp.dis+1});}}if(i==1){//左if(h[xx].size()==1) q.push({xx,n,tmp.dis+1});else{int id=upper_bound(h[xx].begin(),h[xx].end(),yy)-h[xx].begin();if(id!=h[xx].size()) q.push({xx,h[xx][id]-1,tmp.dis+1});else q.push({xx,n,tmp.dis+1});}}if(i==2){//下if(l[yy].size()==1) q.push({1,yy,tmp.dis+1});else{int id=lower_bound(l[yy].begin(),l[yy].end(),xx)-l[yy].begin()-1;if(id!=-1) q.push({l[yy][id]+1,yy,tmp.dis+1});else q.push({1,yy,tmp.dis+1});}}if(i==3){//上if(l[yy].size()==1) q.push({n,yy,tmp.dis+1});else{int id=upper_bound(l[yy].begin(),l[yy].end(),yy)-l[yy].begin();if(id!=l[yy].size()) q.push({l[yy][id]-1,yy,tmp.dis+1});else q.push({n,yy,tmp.dis+1});}}}else {//正常的路if(vis[xx][yy]) continue;q.push({xx,yy,tmp.dis+1});}}}
}int main(){scanf("%d",&n);for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){cin>>a[i][j];if(a[i][j]) {h[i].push_back(j);l[j].push_back(i);} }}for(int i=1;i<=n;i++){sort(l[i].begin(),l[i].end());sort(h[i].begin(),h[i].end());}bfs();if(sign==0) cout<<-1;}
相关文章:

???牛客周赛55:虫洞操纵者
题目描述 \,\,\,\,\,\,\,\,\,\,你需要在一个可以上下左右移动的 nnn\times nnn 棋盘上解开一个迷宫:棋盘四周都是墙;每个方格要么是可以通过的空方格 ′0′\sf 0′0′ ,要么是不可通过的墙方格 ′1′\sf 1′1′ ;你可以沿着空方格…...

Unity3D开发之OnCollisionXXX触发条件
A和B碰撞触发OnCollision函数条件如下: 1.A和B都要有collider。(子物体有也可以) 2.A和B至少有一个刚体(Rigidbody)组件,且刚体的isKinematic为false。如果为true不会触发。 3.挂载脚本的物体必须有刚体…...

spfa()算法(求最短路)
spfa算法是对bellman_ford算法的优化,大部分求最短路问题都可以用spaf算法来求。 注意: (1)如若图中有负权回路,不能用spfa算法,要用bellman_ford算法;若只有负权边,则可以用 spf…...

聊聊国产数据库的生态系统建设
生态系统是指在自然界中,生物与环境构成统一的整体,之间相互影响相互制约,并在一定时期内处于相对稳定的动态平衡状态。所谓数据库的生态系统,从用户的角度看,就是充分打通产品使用过程中上下游的关联,使其…...

JDK源码解析:LinkedList
1、背景 我们咨询一下腾讯混元大模型,什么是“LinkedList”。 以下是混元大模型的回答: LinkedList 是 Java 集合框架中的一种数据结构,它实现了 List 和 Deque 接口。LinkedList 是一个双向链表,这意味着每个元素都包含对前一个和…...

drawio的问题
drawio的问题 先给出drawio的链接https://app.diagrams.net/ 我在用overleaf写论文的过程中,发现了一个问题,就是使用drawio画好图之后,只能保存以下几个选项: 但是不管是什么类型,在overleaf上面图片都不显示。如果…...

零基础学习Redis(3) -- Redis常用命令
Redis是一个 客户端-服务器 结构的程序,Redis客户端和服务器可以在同一台主机上,也可以在不同主机上,客户端和服务器之间通过网络进行通信。服务器端负责存储和管理数据。客户端则可以通过命名对服务端的数据进行操作。 Redis客户端有多种&a…...

响应式Web设计:纯HTML和CSS的实现技巧-1
响应式Web设计(Responsive Web Design, RWD)是一种旨在确保网站在不同设备和屏幕尺寸下都能良好运行的网页设计策略。通过纯HTML和CSS实现响应式设计,主要依赖于媒体查询(Media Queries)、灵活的布局、可伸缩的图片和字…...

FrereRTOS事件组
文章目录 一、事件组概念与操作1、事件组的概念2、事件组的操作 二、事件组函数1、创建2、删除3、设置事件4、等待事件5、同步点 三、示例:广播四、示例:等待一个任意事件五、示例: 等待多个事件都发生 学校组织秋游,组长在等待: …...

【经典算法】BFS_最短路问题
目录 1. 最短路问题介绍2. 算法原理和代码实现(含题目链接)1926.迷宫中离入口最近的出口433.最小基因变化127.单词接龙675.为高尔夫比赛砍树 3. 算法总结 1. 最短路问题介绍 最短路径问题是图论中的一类十分重要的问题。本篇文章只介绍边权为1(或边权相同)的最简单的最短路径问…...

【题目/训练】:双指针
引言 我们已经在这篇博客【算法/学习】双指针-CSDN博客里面讲了双指针、二分等的相关知识。 现在我们来做一些训练吧 经典例题 1. 移动零 思路: 使用 0 当做这个中间点,把不等于 0(注意题目没说不能有负数)的放到中间点的左边,等于 0 的…...

LLVM - 编译器后端-指令选择
一:概述 任何后端的核心都是指令选择。LLVM 实现了几种方法;在本篇文章中,我们将通过选择有向无环图(DAG)和全局指令选择来实现指令选择。 在本篇文章中,我们将学习以下主题: • 定义调…...

ES+FileBeat+Kibana日志采集搭建体验
1.环境准备 需要linux操作系统,并安装了docker环境 此处使用虚拟机演示。(虚拟机和docker看参考我之前写的文章) VirtualBox安装Oracle Linux 7.9全流程-CSDN博客 VirtualBox上的Oracle Linux虚拟机安装Docker全流程-CSDN博客 简单演示搭建ES…...

Dockerfile常用指令详解
Dockerfile 是一个用于定义 Docker 镜像构建过程的脚本文件,其中包含了一系列指令,用于指定如何构建和配置镜像。以下是一些常用的 Dockerfile 指令及其示例用法: 1. FROM 指定基础镜像,Dockerfile 必须以该指令开始。 示例&am…...

【vue】浏览器兼容相关
Vue.js 是一个流行的前端 JavaScript 框架,它支持构建单页应用和复杂的用户界面。Vue.js 的核心库本身对浏览器的支持情况如下: Vue.js 2.x 最低支持版本:IE9 及以上版本。特性支持:ES5。兼容性:Vue 2.x 在发布时就考…...

【区块链+金融服务】基于区块链的区域股权金融综合服务平台 | FISCO BCOS应用案例
区域性股权市场是我国资本市场的重要组成部分,是多层次资本市场体系的基石。区块链技术与区域性股权市场 分散特征天然匹配,从新型金融基础设施层面为场外参与各方提供公共的可信服务,以技术手段完善市场基础条 件,弥补区域性短板…...

string字符串和json对象相互转换问题
//响应体String responseStr EntityUtils.toString(response.getEntity());log.debug("下单响应码:{},响应体:{}",statusCode,responseStr);if(statusCode HttpStatus.OK.value()){JSONObject jsonObject JSONObject.parseObject(responseStr);if(jsonObject.cont…...

【生成式人工智能-十一一个不修改模型就能加速语言模型生成的方法】
一个加速语言模型生成的方法 现在语言模型的一个弊端speculative decoding预言家预测的问题 speculative decoding 模块的实现方法NAT Non-autoregressive模型压缩使用搜索引擎 一些更复杂些的speculative decoding 实现方式 speculative decoding 是一个适用于目前生成模型的加…...

Rust 错误处理
Rust 错误处理 Rust 是一种系统编程语言,以其内存安全、高并发和实用性而著称。在 Rust 中,错误处理是一个核心概念,它通过提供 Result 和 Option 类型来鼓励开发者显式地处理可能出现的错误,而不是依赖异常机制。本文将深入探讨 Rust 中的错误处理机制,包括 Result 和 O…...

程序与进程 linux系统
程序与进程 程序 ( program ): 通常为 binary program ,放置在储存媒体中(如硬盘、光盘、软盘、磁带等), 为实体文件的型态存在;二进制文件,比如静态 /bin/date…...

使用MongoDB构建AI:Story Tools Studio将生成式AI引入Myth Maker AI游戏
Story Tools Studio利用先进的生成式AI技术,打造沉浸式、个性化、无穷尽的情景体验。 Story Tools Studio创始人兼首席执行官Roy Altman表示:“我们的旗舰游戏Myth Maker AI采用的是我们自主研发的、以AI为驱动的专家指导型故事生成器MUSE,它…...

鸿蒙UIAbility组件概述(二)
鸿蒙UIAbility组件概述 UIAbility组件基本用法指定UIAbility的启动页面获取UIAbility的上下文信息 UIAbility组件与UI的数据同步使用EventHub进行数据通信使用AppStorage/LocalStorage进行数据同步 UIAbility组件间交互(设备内)启动应用内的UIAbility启动…...

Oracle(70)如何优化SQL查询?
优化SQL查询是数据库管理的重要部分,旨在提高查询性能,减少响应时间和资源消耗。以下是一些常见的SQL查询优化技术,结合代码示例详细说明。 1. 使用索引 索引是优化查询性能的最常见方法之一。索引可以显著减少数据检索的时间。 示例 假设…...

深度剖析:Jenkins构建任务无法中断的原因及解决方案
个人名片 🎓作者简介:java领域优质创作者 🌐个人主页:码农阿豪 📞工作室:新空间代码工作室(提供各种软件服务) 💌个人邮箱:[2435024119qq.com] 📱…...

【YOLO】常用脚本
目录 VOC转YOLO划分训练集、测试集与验证集 VOC转YOLO import os import xml.etree.ElementTree as ETdef convert(size, box):dw 1. / size[0]dh 1. / size[1]x (box[0] box[1]) / 2.0y (box[2] box[3]) / 2.0w box[1] - box[0]h box[3] - box[2]x x * dww w * dwy…...

Springboot IOC DI理解及实现+JUnit的引入+参数配置
一、JavaConfig 我们通常使用 Spring 都会使用 XML 配置,随着功能以及业务逻辑的日益复杂,应用伴随着大量的 XML 配置文件以及复杂的 bean 依赖关系,使用起来很不方便。 在 Spring 3.0 开始,Spring 官方就已经开始推荐使用 Java…...

CeresPCL 最小二乘插值(曲线拟合)
一、简介 在多项式插值时,当数据点个数较多时,插值会导致多项式曲线阶数过高,带来不稳定因素。因此我们可以通过固定幂基函数的最高次数 m(m < n),来对我们要拟合的曲线进行降阶。之前的函数形式就可以变为: 既然是最小二乘问题,那么就仍然可以使用Ceres来进行求解。 …...

【TCP/IP】自定义应用层协议,常见端口号
互联网中,主流的是 TCP/IP 五层协议 5G/4G 上网,是有自己的协议栈,要比 TCP/IP 更复杂(能够把 TCP/IP 的一部分内容给包含进去了) 应用层 可以代表我们所编写的应用程序,只要应用程序里面用到了网络通信…...

Frida 的下载和安装
首先要安装好 python 环境 安装 frida 和 工具包 pip install frida frida-tools 查看版本: frida --version 16.4.8 然后到 github 上下载对应 server ( 和frida 的版本一致 16.4.8) Releases frida/frida (github.com) 查看手机或…...

后端开发刷题 | 链表内指定区间反转【链表篇】
描述 将一个节点数为 size 链表 m 位置到 n 位置之间的区间反转,要求时间复杂度 O(n)O(n),空间复杂度 O(1)O(1)。 例如: 给出的链表为 1→2→3→4→5→NULL1→2→3→4→5→NULL, m2,n4 返回 1→4→3→2→5→NULL 数据范围: 链表…...