石碑之谜:滚动机关

描述

在蒙德和璃月的边界地带,有一个被遗忘的神庙,里面有一个奇怪的机关:滚动石碑。小熊必须操作这个1×1×2的长方体石碑,使其通过不同的地面环境,最终放置到神秘的符号“O”上,以解开通往宝藏的大门。

石碑可以有三种放置形式:

  • 立在地面上(1×1的面接触地面)。
  • 横躺在地面上(1×2的面接触地面),似乎是为了休息或避开某些地面的损害。
  • 竖趟在地面上(1×2的面接触地面)

地图是一个N行M列的矩阵,代表着充满未知的遗迹内部:

  • 正常的地面由“.”表示,平坦且安全。
  • 易碎的地面用“E”标识,石碑不能以全部重量压在这种地面上,特别是立着时。
  • 不能通过的地面用“#”表示,这可能是古代结界或坍塌的部分。
  • 起点用“X”表示,石碑的初始位置。
  • 终点由“O”标识,是需要将石碑立在其上的目标位置。

小熊通过上下左右四个方向键来控制石碑沿边缘滚动90°。在整个探索过程中,石碑不能碰到不可通过的地面,也不能在易碎地面上以1×1的面立着。

地图上的“X”可能标识一个或两个相邻的位置,显示石碑是初始时是立着还是躺着的状态。

小熊的任务是以最少的步数,将石碑正确地立在“O”上,揭开这片古老土地的秘密。

image.png

image.png

image.png

输入

输入包含多组测试用例。

对于每个测试用例,第一行包括两个整数N和M。

接下来N行用来描述地图,每行包括M个字符,每个字符表示一块地面的具体状态。

当输入用例N=0,M=0时,表示输入终止,且该用例无需考虑。

数据范围

3≤N,M≤500

输出

对于每个测试用例,输出一个整数,表示小熊将石碑从起点推到目标点所需的最少步数。如果石碑无法成功地被推至目标点,则输出"Impossible"。

每个测试用例的结果输出在单独的一行。

输入样例 1 
7 7
#######
#..X###
#..##O#
#....E#
#....E#
#.....#
#######
0 0
输出样例:

10

代码实现:

#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
const int N=510;
char area[N][N];
int dist[N][N][3];
int n,m;
struct stone
{//立0    横1    竖2int x,y,st;stone(int a,int b,int c){x=a,y=b,st=c;}stone():x(0),y(0),st(0){};
};
stone start,target;int dxyz[4][3][3]={//dxyz[i][st][x,y,st]{{-2,0,2},{-1,0,1},{-1,0,0}},//向上{{0,-2,1},{0,-1,0},{0,-1,2}},//向左{{1,0,2},{1,0,1},{2,0,0}},//向下{{0,1,1},{0,2,0},{0,1,2}}//向右};
stone movestone(stone &p,int i)
{int x=p.x+dxyz[i][p.st][0];int y=p.y+dxyz[i][p.st][1];int z=dxyz[i][p.st][2];return stone(x,y,z);
}
bool isInside(int i,int j)
{return (i>=0&&j>=0&&i<n&&j<m);
}
bool isValid(stone s)
{if(!isInside(s.x,s.y)||area[s.x][s.y]=='#')return false;if(s.st==1&&(!isInside(s.x,s.y+1)||area[s.x][s.y+1]=='#'))return false;if(s.st==2&&(!isInside(s.x+1,s.y)||area[s.x+1][s.y]=='#'))return false;if(s.st==0&&area[s.x][s.y]=='E')return false;return true;
}
bool isVisited(stone t)
{return dist[t.x][t.y][t.st]!=-1;
}
int bfs(stone& s)
{queue<stone> q;q.push(s);dist[s.x][s.y][s.st]=0;while(q.size()){auto t=q.front();q.pop();for(int i=0;i<4;i++){stone p=movestone(t,i);if(!isValid(p))continue;if(!isVisited(p)){dist[p.x][p.y][p.st]=dist[t.x][t.y][t.st]+1;q.push(p);if(p.x==target.x&&p.y==target.y&&p.st==target.st)return dist[p.x][p.y][p.st];}}}return -1;
}
int main()
{while(cin>>n>>m&&n){memset(area,'#',sizeof area);memset(dist,-1,sizeof dist);for(int i=0;i<n;i++)cin>>area[i];for(int i=0;i<n;i++)for(int j=0;j<m;j++){char t=area[i][j];if(t=='X'){start.x=i,start.y=j,start.st=0;area[i][j]='.';if(area[i][j+1]=='X')start.st=1,area[i][j+1]='.';if(area[i+1][j]=='X')start.st=2,area[i+1][j]='.';}if(t=='O')target.x=i,target.y=j,target.st=0;}int res=bfs(start);if(res==-1)cout<<"Impossible"<<endl;else cout<<res<<endl;}return 0;
}

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

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

相关文章

【智能算法】清道夫优化算法(CFO)原理及实现

目录 1.背景2.算法原理2.1算法思想2.2算法过程 3.结果展示4.参考文献5.代码获取 1.背景 2024年&#xff0c;W Zhang受到清道夫自然行为启发&#xff0c;提出了清道夫优化算法&#xff08;Cleaner Fish Optimization Algorithm, CFO&#xff09;。 2.算法原理 2.1算法思想 CF…

【oracle】图片转为字节、base64编码等形式批量插入oracle数据库并查询

1.熟悉、梳理、总结下Oracle相关知识体系 2.欢迎批评指正&#xff0c;跪谢一键三连&#xff01; 资源下载&#xff1a; oci.dll、oraocci11.dll、oraociei11.dll3个资源文件资源下载&#xff1a; Instant Client Setup.exe资源下载&#xff1a; oci.dll、oraocci11.dll、oraoc…

使用Docker进行Jmeter分布式搭建

大家好&#xff0c;随着技术的不断发展&#xff0c;对性能测试的要求也日益提高。在这样的背景下&#xff0c;如何利用 Docker 来巧妙地搭建 Jmeter 分布式成为了关键所在。现在&#xff0c;就让我们开启这场探索之旅&#xff0c;揭开其神秘的面纱。前段时间给大家分享了关于 L…

SQL慢查询学习篇

https://www.cnblogs.com/isyues/p/17733015.html 1. 对扫到的SQL慢查询语句执行 explain explain select task_id, channel, count(task_id) as count from tablename where send_time > "2024-05-10 16:13:59" and send_time < "2024-05-14 16:13:59…

LeetCode 235. 二叉搜索树的最近公共祖先

LeetCode 235. 二叉搜索树的最近公共祖先 1、题目 题目链接&#xff1a;235. 二叉搜索树的最近公共祖先 给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为&#xff1a;“对于有根树 T 的两个结点 p、q&#xff0c;最近公共祖先表…

【C语言】指针(二)

目录 一、传值调用和传址调用 二、数组名的理解 三、通过指针访问数组 四、一维数组传参的本质 五、指针数组 六、指针数组模拟实现二维数组 一、传值调用和传址调用 指针可以用在哪里呢&#xff1f;我们看下面一段代码&#xff1a; #include <stdio.h>void Swap(i…

ue引擎游戏开发笔记(41)——行为树的建立(2)--丰富ai行为:巡逻后返回原处

1.需求分析&#xff1a; 就敌人ai而言&#xff0c;追踪到敌人有可能丢失目标&#xff0c;丢失目标后应该能返回原来位置&#xff0c;实现这一功能。 2.操作实现&#xff1a; 1.思路&#xff1a;利用clear value函数&#xff0c;禁用掉当前的追踪功能&#xff0c;执行之后的返…

JUnit5参数化用例(三)

JUnit5枚举参数的参数化&#xff1a; 使用枚举类作为测试数据枚举参数参数化注解EnumSource必须与ParameterizedTest结合使用 枚举参数化注解 -简单使用&#xff1a; 需要添加EnumSource注解测试方法传入枚举类作为参数 在执行前&#xff0c;我们需了解enum枚举的使用方式&…

分布式计算、并行计算、网格计算、边缘计算

分布式计算 分布式计算是一种计算方法&#xff0c;它将一个大型的计算任务分解成多个子任务&#xff0c;并将这些子任务分布在网络上的多台计算机&#xff08;节点&#xff09;上同时执行。这些节点通过通信网络协同工作&#xff0c;共同完成任务。每个节点可以独立处理自己的…

3D Tiles资源大全

本文汇总整理3D Tiles相关的各种资源&#xff0c;包括查看器、生成器、示例数据集、教程、演示等。 1、3D Tiles特色演示 注意&#xff1a;这些演示是基于 CesiumJS 1.87.1 Release 发布的&#xff0c;其中包括对 3D Tiles Next 扩展的实验性支持。这些演示中显示的大多数功能现…

Java入门基础学习笔记26——break,continue

跳转关键字&#xff1a; break&#xff1a; 跳出并结束当前所在循环的执行。 continue&#xff1a; 用于跳出当前循环中的当次执行&#xff0c;直接进入循环中的下一次执行。 package cn.ensource.loop;public class BreakContinueDemo8 {public static void main(String[] a…

在Ubuntu22.04搭建xfce远程桌面

由于Ubuntu22.04云服务器&#xff08;带GPU&#xff09;只开放部分端口&#xff0c;某些服务&#xff08;如nacos&#xff09;有Web前端需要访问&#xff0c;但是相应的端口并没有开放&#xff0c;只有SSH端口可以使用。于是&#xff0c;就在Ubuntu22.04上安装xfce桌面环境&…