题解:AT_abc170_f [ABC170F] Pond Skater

题目描述

アメンボのすぬけ君は南北 H マス東西 W マスの長方形の形をしたグリッド状の池に住んでいます。北から i 番目、西から j 番目のマスをマス (i,j) とします。

いくつかのマスには蓮の葉が浮かんでおり、すぬけ君はそれらのマスには入ることができません。 cij​ が @ のときマス (i,j) に蓮の葉が浮かんでいること、.のときそうでないことを表します。

すぬけ君は一回水をかくことで東西南北のいずれかの方向に 1 マス以上 K マス以下移動することができます。 移動の途中に蓮の葉のあるマスがあってはいけません。また、蓮の葉のあるマスや池の外に移動することもできません。

すぬけ君がマス (x1​,y1​) から (x2​,y2​) まで移動するのに最小で何回水をかく必要があるか求めてください。 (x1​,y1​) から (x2​,y2​) まで移動することができない場合、そのことを指摘してください。

输入格式

入力は以下の形式で標準入力から与えられる。

H W K

x1​ y1​ x2​ y2​

c1,1 ​c1,2​ .. c1,W​  

c2,1​ c2,2​  .. c2,W​ 

...

cH,1​ cH,2​ .. cH,W​ 

输出格式

すぬけ君がマス (x1​,y1​) から (x2​,y2​) まで移動するのに必要な最小の水かきの回数を出力せよ。 (x1​,y1​) から (x2​,y2​) まで移動することができない場合、-1を出力せよ。

题意翻译

你在一个划分为上下 H 行,左右 W 列的长方形网格中,网格从上到下的第 i 行的从左往右第 j 列被编号为 (i,j) ,如果 c_{i,j} 为 @ ,则 (i,j) 不能通过。

你现在在 (x1​,y1​),你每步可以往上下左右走 1 至 K 格,问你最少需要多少步才能走到 (x2​,y2​) ,如果不能走到,输出 −1 。

输入先是一行三个整数 H,W,K ,再是一行四个整数 x1​,y1​,x2​,y2​,接着是 H×W 的字符矩阵,第 i 行 j 列表示 c_{i,j} 。

输入输出样例

输入 #1

3 5 2
3 2 3 4
.....
.@..@
..@..

输出 #1

5

输入 #2

1 6 4
1 1 1 6
......

输出 #2

2

输入 #3

3 3 1
2 1 2 3
.@.
.@.
.@.

输出 #3

-1

说明/提示

制約

  • 1 ≤ H,W,K ≤ 106
  • H × W ≤ 106
  • 1 ≤ x1​,x2​ ≤ H
  • 1 ≤ y1​,y2​ ≤ W
  • x1​ ≠ x2​ または y1​ ≠ y2​
  • ci,j​ は . または @
  • cx1​,y1​​ = .
  • cx2​,y2​​ = .
  • 入力される数はすべて整数である。

Sample Explanation 1

はじめ、すぬけ君はマス (3,2) にいます。 以下のように 5 回水をかくことでマス (3,4) まで移動することができます。 - マス (3,2) から西に 1 マス進み、マス (3,1) に移動する。 - マス (3,1) から北に 2 マス進み、マス (1,1) に移動する。 - マス (1,1) から東に 2 マス進み、マス (1,3) に移動する。 - マス (1,3) から東に 1 マス進み、マス (1,4) に移動する。 - マス (1,4) から南に 2 マス進み、マス (3,4) に移動する。

题目大意

题目背景:
水黾(アメンボ)“すぬけ君”生活在一个呈南北 H 格、东西 W 格的矩形网格状池塘中。我们把从北往南数第 i 行、从西往东数第 j 列的格子称为格子 (i,j)。

池塘中有些格子上漂浮着莲叶,すぬけ君无法进入这些格子。若 c_{i,j}​ 的值为 “@”,表示格子 (i,j) 上有莲叶;若其值为 “.”,则表示格子 (i,j) 没有莲叶。

すぬけ君一次划水可以向东、南、西、北任意一个方向移动 1 到 K 格。但移动路径上经过的所有格子都不能有莲叶,且最终落脚的格子也不能有莲叶。同时,不能移动到池塘范围之外。

请计算:すぬけ君从格子 (x_1, y_1) 移动到格子 (x_2, y_2) 所需的最少划水次数。如果无法从 (x_1, y_1)(x_2, y_2),请指出无法到达。


输入格式:
从标准输入中给出的格式如下:

H W K x1 y1 x2 y2
c1,1 c1,2 … c1,W
c2,1 c2,2 … c2,W
:
cH,1 cH,2 … cH,W

  • H,W 分别为池塘南北、东西方向的格子数。
  • K 为すぬけ君一次划水最多能移动的格子数。
  • (x_1, y_1)(x_2, y_2) 分别是起点格子与目标格子的位置(用「北往南数第 x 行,西往东数第 y 列」的方式表示)。
  • 接下来的 H 行,每行包含 W 个字符(“@” 或 “.”),表示池塘中每个格子是否有莲叶。

输出格式:
输出すぬけ君从格子 (x_1, y_1) 移动到 (x_2, y_2) 所需的最少划水次数;若无法到达,请输出 -1

思路

考虑用 bfs()(广度优先搜索) 做此题。
由于 1 ≤ H,W,K ≤ 106,但没有说明 w,k 的具体大小,所以不能用二维数组存,会爆空间。要改为用一维数组存。
如何表示到下一行呢?只需要加上一个 w 即可。 但是普通的 bfs() 会超时。
容易发现现在队头的坐标 (x,y) 往某个方向走到一定程度时,当前坐标 (x2​,y2​) 需要走的步数小于现在队头的步数 +1 ,此时就可以停止往这个方向的搜索,因为从 (x2​,y2​) 已经比从 (x,y) 更优了。以下是最基本的广度优先搜索(bfs())做这题的步骤:

  • 使用 BFS(广度优先搜索)算法求最短路径。每一次水划被视作一步,每个状态是当前所在的格子。
  • 对于每个格子,我们尝试向四个方向扩展,步长从1到K。遇到边界、障碍物或者遇到已经用更少或相同次数到达的格子时,就停止当前方向的扩展。
  • 用二维数组记录到达每个格子的最少水划次数,初始状态设为极大值。
  • 当终点被访问时即输出结果;如果搜索完毕后未能到达终点,则输出-1。

代码

#include<bits/stdc++.h>
using namespace std;
struct stu{int f,s;
};
int ax,h,w,k,x1,yy1/*y1关键字,避坑!!!*/,x2,y2,xx,zz,a[1000010],dx[5]/*一维数组,用来计算一维坐标*/,gx[5]={-1,1,0,0},gy[5]={0,0,-1,1}/*gx,gy表示实际改变的x,y坐标增加了多少*/,ans=1e9;//gy!!!
int vis[1000010];//现在走到一维数组的某个位置最少需要多少步 
char c;
queue<int>x,z;//一维坐标和步数 
queue<stu>y;//表示实际坐标(可以不用,但更麻烦,会卡常的可以试一下) 
stu yy;
void bfs(){while(!x.empty()){xx=x.front(),yy=y.front(),zz=z.front();x.pop(),y.pop(),z.pop();if(xx==(x2-1)*w+y2){ans=min(ans,zz);return ;}for(int i=0;i<4;i++){for(int j=1;j<=k;j++){ax=xx+dx[i]*j;//现在的一维坐标 if(!(yy.f+gx[i]*j>=1&&yy.f+gx[i]*j<=h&&yy.s+gy[i]*j>=1&&yy.s+gy[i]*j<=w))break;if(vis[ax]==zz+1)continue;if(!(vis[ax]>zz+1&&a[ax]))break;//可以通过 vis[ax]=zz+1;x.push(ax),y.push({yy.f+gx[i]*j,yy.s+gy[i]*j}),z.push(zz+1);}}	}
}
int main(){cin>>h>>w>>k>>x1>>yy1>>x2>>y2;dx[0]=-w;//上 dx[1]=w;//下dx[2]=-1;//左dx[3]=1;//右 for(int i=1;i<=h*w;i++)vis[i]=1e9;//初始化 for(int i=1;i<=h;i++){for(int j=1;j<=w;j++){cin>>c;if(c=='.')a[(i-1)*w+j]=1;else a[(i-1)*w+j]=0;}}x.push((x1-1)*w+yy1);//一维坐标 y.push({x1,yy1});//二维坐标 z.push(0);vis[(x1-1)*w+yy1]=0;bfs();if(ans==1e9)cout<<-1;else cout<<ans;cout<<endl;return 0;
}

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

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

相关文章

Kafka日志管理系统深度解析

Kafka日志管理系统深度解析 在分布式消息队列领域&#xff0c;Kafka因其高性能、可扩展性和可靠性而广受欢迎。而日志管理系统是Kafka的核心基础设施&#xff0c;它直接决定了Kafka的性能表现和可靠性保证。 分段式存储设计 Kafka采用分段式存储设计&#xff0c;将每个分区的…

DeepSeek、Grok 与 ChatGPT 4.5:新一代大模型架构与推理能力深度解析

近年来&#xff0c;大语言模型&#xff08;LLM&#xff09;领域发展迅猛&#xff0c;DeepSeek、Grok 以及 OpenAI 最新发布的 ChatGPT 4.5 都是该领域的代表性产品。本文将从架构设计、推理能力、训练策略等方面&#xff0c;对三者进行技术对比&#xff0c;探讨其优势与潜在的应…

Oracle数据库性能优化全攻略:十大关键方向深度解析与实践指南

文章目录 一、SQL查询优化二、索引优化三、内存管理四、I/O优化五、分区表与分区索引六、并行处理七、统计信息管理八、锁与并发控制九、数据库参数调优十、应用设计优化结论 在当今数据驱动的时代&#xff0c;数据库的性能优化成为了确保企业应用高效运行的关键。Oracle作为业…

Git 使用SSH登陆

一、SSH介绍 SSH连接相比于HTTP连接会简单一点&#xff0c;因为SSH连接通过了私钥与公钥进行身份认证&#xff0c;这样就不需要像HTTP一样&#xff0c;每次clone或者操作仓库都需要输入密码 其中私钥和密钥是需要在自己电脑上生成的&#xff0c;通过命令即可生成一个私钥和一个…

openharmony中hilog实证记录说明(3.1和5.0版本)

每次用这个工具hilog都有一些小用法记不清&#xff0c;需要花一些时间去查去分析使用方法&#xff0c;为了给丰富多彩的生活留出更多的时间&#xff0c;所以汇总整理共享来了&#xff0c;它来了它来了~~~~~~~~~ 开始是想通过3.1来汇总的&#xff0c;但实际测试发现openharmony…

UDP 协议

文章目录 UDP 协议简介数据包格式UDP 通信流程抓包分析参考 本文为笔者学习以太网对网上资料归纳整理所做的笔记&#xff0c;文末均附有参考链接&#xff0c;如侵权&#xff0c;请联系删除。 UDP 协议 UDP 是一种面向无连接的传输层协议&#xff0c;属于 TCP/IP 协议簇的一种。…

数据结构之链表(双链表)

目录 一、双向带头循环链表 概念 二、哨兵位的头节点 优点&#xff1a; 头节点的初始化 三、带头双向链表的实现 1.双链表的销毁 2.双链表的打印 3.双链表的尾插和头插 尾插&#xff1a; 头插&#xff1a; 4.双链表的尾删和头删 尾删&#xff1a; 头删&#xff1a; …

内存取证之windows-Volatility 3

一&#xff0c;Volatility 3下载 1.安装Volatility 3。 要求&#xff1a;python3.7以上的版本&#xff0c;我的是3,11&#xff0c;这里不说python的安装方法 使用 pip 安装 Volatility 3&#xff1a; pip install volatility3 安装完成后&#xff0c;验证安装&#xff1a; v…

Unity的JSON工具类+LitJson的引入及使用

C#使用JSON数据 数据存储&#xff08;序列化&#xff09;&#xff1a;将C#的数据格式&#xff0c;转化为JSON字符串&#xff0c;存储或传输 数据使用&#xff08;反序列化&#xff09;&#xff1a;将JSON字符串中存储的数据&#xff0c;转化为C#可用的数据格式&#xff0c;实现…

WX小程序

下载 package com.sky.utils;import com.alibaba.fastjson.JSONObject; import org.apache.http.NameValuePair; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.Cl…

MyBatis 中 #{} 和 ${} 的区别详解

目录 1. #{} 和 ${} 的基本概念 1.1 #{} 1.2 ${} 2. #{} 和 ${} 的工作原理 2.1 #{} 的工作原理 2.2 ${} 的工作原理 3.共同点&#xff1a;动态 SQL 查询 4. 区别&#xff1a;处理方式和适用场景 4.1 处理方式 4.2 适用场景 &#xff08;1&#xff09;#{} 的适用场景…

【蓝桥杯速成】| 10.回溯切割

前面两篇内容我们都是在做有关回溯问题的组合应用 今天的题目主题是&#xff1a;回溯法在切割问题的应用 题目一&#xff1a;分割回文串 问题描述 131. 分割回文串 - 力扣&#xff08;LeetCode&#xff09; 给你一个字符串 s&#xff0c;请你将 s 分割成一些 子串&#xff…

数据结构之双向链表-初始化链表-头插法-遍历链表-获取尾部结点-尾插法-指定位置插入-删除节点-释放链表——完整代码

数据结构之双向链表-初始化链表-头插法-遍历链表-获取尾部结点-尾插法-指定位置插入-删除节点-释放链表——完整代码 #include <stdio.h> #include <stdlib.h>typedef int ElemType;typedef struct node{ElemType data;struct node *next, *prev; }Node;//初化链表…

开源视频剪辑工具,无损编辑更高效

LosslessCut 是一款基于 FFmpeg 开发的跨平台开源视频剪辑工具&#xff0c;致力于无损处理音视频文件。它无需重新编码即可完成剪切、合并、轨道编辑等操作&#xff0c;极大地保留了原始文件的质量&#xff0c;特别适合处理大体积视频&#xff0c;如无人机拍摄素材或长时录制内…

Java:Apache HttpClient中HttpRoute用法的介绍

当使用Apache HttpClient组件时&#xff0c;经常会用到它的连接池组件。典型的代码如下&#xff1a; PoolingHttpClientConnectionManager connectionManager new PoolingHttpClientConnectionManager();connectionManager.setMaxTotal(httpConfig.getMaxPoolTotal());connect…

EasyRTC嵌入式音视频通信SDK:WebRTC技术下的硬件与软件协同演进,开启通信新时代

在当今数字化时代&#xff0c;智能设备的普及和人们对实时通信需求的不断增长&#xff0c;推动了嵌入式音视频通信技术的快速发。EasyRTC嵌入式音视频通信SDK凭借其独特的技术特点和应用优势&#xff0c;在嵌入式设备和多平台实时通信领域脱颖而出。 1、轻量级设计与高性能 Ea…

Uthana,AI 3D角色动画生成平台

Uthana是什么 Uthana 是专注于3D角色动画生成的AI平台。平台基于简单的文字描述、参考视频或动作库搜索&#xff0c;快速为用户生成逼真的动画&#xff0c;支持适配任何骨骼结构的模型。Uthana 提供风格迁移、API集成和定制模型训练等功能&#xff0c;满足不同用户需求。平台提…

Python:多线程创建的语法及步骤

线程模块&#xff1a;import threading 线程类Thread参数&#xff1a;group(线程组) target&#xff1a;执行的目标的任务名 args&#xff1a;以元组的方式给执行任务进行传参 *args可以传任意多个参数 kwargs以字典方式给执行任务传参 name&#xff1a;线程名 步骤&…

Jupyter Notebook 常用命令(自用)

最近有点忘记了一些常见命令&#xff0c;这里就记录一下&#xff0c;懒得找了。 文章目录 一、文件操作命令1. %cd 工作目录2. %pwd 显示路径3. !ls 列出文件4. !cp 复制文件5. !mv 移动或重命名6. !rm 删除 二、代码调试1. %time 时间2. %timeit 平均时长3. %debug 调试4. %ru…

快速入手-基于Django的Form和ModelForm操作(七)

1、Form组件 2、ModelForm操作 3、给前端表单里在django里添加class相关属性值 4、前端 5、后端form 新增数据处理 6、更新数据处理