AcWing 立体推箱子
题目描述
立体推箱子是一个风靡世界的小游戏。
游戏地图是一个N行M列的矩阵,每个位置可能是硬地(用”.”表示)、易碎地面(用”E”表示)、禁地(用”#”表示)、起点(用”X”表示)或终点(用”O”表示)。
你的任务是操作一个1×1×2的长方体。
这个长方体在地面上有两种放置形式,“立”在地面上(1×1的面接触地面)或者“躺”在地面上(1×2的面接触地面)。
在每一步操作中,可以按上下左右四个键之一。
按下按键之后,长方体向对应的方向沿着棱滚动90度。
任意时刻,长方体不能有任何部位接触禁地,并且不能立在易碎地面上。
字符”X”标识长方体的起始位置,地图上可能有一个”X”或者两个相邻的”X”。
地图上唯一的一个字符”O”标识目标位置。
求把长方体移动到目标位置(即立在”O”上)所需要的最少步数。
在移动过程中,”X”和”O”标识的位置都可以看作是硬地被利用。
输入格式
输入包含多组测试用例。
对于每个测试用例,第一行包括两个整数N和M。
接下来N行用来描述地图,每行包括M个字符,每个字符表示一块地面的具体状态。
当输入用例N=0,M=0时,表示输入终止,且该用例无需考虑。
输出格式
每个用例输出一个整数表示所需的最少步数,如果无解则输出”Impossible”。
每个结果占一行。
数据范围
3≤N,M≤500
样例
input
7 7
#######
#..X###
#..##O#
#....E#
#....E#
#.....#
#######
0 0
output
10
分析
太毒瘤了
码农题
将方块压成结构体,标记(xxx.op)分三种:
1.竖着
2.横躺着
3.竖躺着
然后就是裸的广搜了
(记得开vis数组记录是否被访问过,否则\(MLE\))
Code
#include<bits/stdc++.h>
using namespace std;
struct node
{
int x,y,op,num;
};
int n,m,arr[510][510],tox,toy,startop,stax[3],stay[3],vis[4][510][510];
char ip;
queue<node>q;
int BFS()
{
while(!q.empty())
{
node t=q.front();
q.pop();
if(vis[t.op][t.x][t.y])
{
continue;
}
vis[t.op][t.x][t.y]=1;
if(t.op==1&&t.x==tox&&t.y==toy)
{
return t.num;
}
if(t.op==1)
{
if(t.x+2>=1&&t.x+2<=n&&t.y>=1&&t.y<=m)
{
if(arr[t.x+1][t.y]&&arr[t.x+2][t.y])
{
q.push(node{t.x+1,t.y,2,t.num+1});
}
}
if(t.x-2>=1&&t.x-2<=n&&t.y>=1&&t.y<=m)
{
if(arr[t.x-1][t.y]&&arr[t.x-2][t.y])
{
q.push(node{t.x-2,t.y,2,t.num+1});
}
}
if(t.x>=1&&t.x<=n&&t.y+2>=1&&t.y+2<=m)
{
if(arr[t.x][t.y+1]&&arr[t.x][t.y+2])
{
q.push(node{t.x,t.y+1,3,t.num+1});
}
}
if(t.x>=1&&t.x<=n&&t.y-2>=1&&t.y-2<=m)
{
if(arr[t.x][t.y-1]&&arr[t.x][t.y-2])
{
q.push(node{t.x,t.y-2,3,t.num+1});
}
}
}
if(t.op==2)
{
if(t.x>=1&&t.x<=n&&t.y+1>=1&&t.y+1<=m)
{
if(arr[t.x][t.y+1]&&arr[t.x+1][t.y+1])
{
q.push(node{t.x,t.y+1,2,t.num+1});
}
}
if(t.x>=1&&t.x<=n&&t.y-1>=1&&t.y-1<=m)
{
if(arr[t.x][t.y-1]&&arr[t.x+1][t.y-1])
{
q.push(node{t.x,t.y-1,2,t.num+1});
}
}
if(t.x+2>=1&&t.x+2<=n&&t.y>=1&&t.y<=m)
{
if(arr[t.x+2][t.y]&&arr[t.x+2][t.y]!=2)
{
q.push(node{t.x+2,t.y,1,t.num+1});
}
}
if(t.x-1>=1&&t.x-1<=n&&t.y>=1&&t.y<=m)
{
if(arr[t.x-1][t.y]&&arr[t.x-1][t.y]!=2)
{
q.push(node{t.x-1,t.y,1,t.num+1});
}
}
}
if(t.op==3)
{
if(t.x+1>=1&&t.x+1<=n&&t.y>=1&&t.y<=m)
{
if(arr[t.x+1][t.y]&&arr[t.x+1][t.y+1])
{
q.push(node{t.x+1,t.y,3,t.num+1});
}
}
if(t.x-1>=1&&t.x-1<=n&&t.y>=1&&t.y<=m)
{
if(arr[t.x-1][t.y]&&arr[t.x-1][t.y+1])
{
q.push(node{t.x-1,t.y,3,t.num+1});
}
}
if(t.x>=1&&t.x<=n&&t.y+2>=1&&t.y+2<=m)
{
if(arr[t.x][t.y+2]&&arr[t.x][t.y+2]!=2)
{
q.push(node{t.x,t.y+2,1,t.num+1});
}
}
if(t.x>=1&&t.x<=n&&t.y-1>=1&&t.y-1<=m)
{
if(arr[t.x][t.y-1]&&arr[t.x][t.y-1]!=2)
{
q.push(node{t.x,t.y-1,1,t.num+1});
}
}
}
}
return 0;
}
int main()
{
//freopen("pushbox.in","r",stdin);
while(cin>>n>>m&&n&&m)
{
memset(arr,0,sizeof(arr));
memset(vis,0,sizeof(vis));
startop=0;
while(!q.empty())
{
q.pop();
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cin>>ip;
if(ip=='.')
{
arr[i][j]=1;
}
if(ip=='E')
{
arr[i][j]=2;
}
if(ip=='O')
{
arr[i][j]=1;
tox=i;
toy=j;
}
if(ip=='X')
{
startop++;
arr[i][j]=1;
stax[startop]=i;
stay[startop]=j;
}
}
}
if(startop==1)
{
q.push(node{stax[1],stay[1],1,0});
}
else
{
if(stax[1]!=stax[2])
{
q.push(node{stax[1],stay[1],2,0});
}
else
{
q.push(node{stax[1],stay[1],3,0});
}
}
int ans=BFS();
if(!ans)
{
cout<<"Impossible"<<endl;
continue;
}
cout<<ans<<endl;
}
}