题意:
给你一个箱子和箱子开始时摆放的方式,通过滚动箱子将其摆放到目标位置,其中有三种地板状态(坚硬的,易碎的,空的)分别能承受不同的箱子重量,求出最少滚动的次数。
分析:
用三维数组标记走过的状态,每次只需记录一个格子的情况。
代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<string>
#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<vector>
#include<stack>
#include<cstdlib>
#define LL long long
#define pi acos(-1.0)
#define PB push_back()
#define MP make_pair()
#define BG begin()
#define ED end()
#define clr(a,b) memset(a,b,sizeof(a))
#define inf 0x3f3f3f3f
#define Mod 1e9+7
using namespace std;
const int maxn=505;
char A[maxn][maxn];
int vis[maxn][maxn][3];
int n,m;
struct node
{
int x,y,w;
int step;
};
bool judge(int x,int y)
{
return x>=0&&x<n&&y>=0&&y<m;
}
bool judge1(int x,int y,int w)
{
if(judge(x,y)&&A[x][y]!='#'){
if(w==0)
return A[x][y]!='E';
else if(w==1)
return judge(x,y+1)&&A[x][y+1]!='#';
else if(w==2)
return judge(x+1,y)&&A[x+1][y]!='#';
}
else
return 0;
}
int dir[4][2]={0,-1,1,0,0,1,-1,0};
int slove(int sx,int sy,int sw)
{
queue<node> Q;
node st,ed;
int dx,dy,dw,ds;
st.x=sx;
st.y=sy;
st.w=sw;
st.step=0;
Q.push(st);
vis[sx][sy][sw]=1;
while(!Q.empty())
{
st=Q.front();
Q.pop();
if(A[st.x][st.y]=='O'&&st.w==0){
return st.step;
}
for(int i=0;i<4;i++){
dx=st.x+dir[i][0];
dy=st.y+dir[i][1];
ds=st.step+1;
if(st.w==0)
{
if(i==0){
dy--;
dw=1;
}
else if(i==1){
dw=2;
}
else if(i==2){
dw=1;
}
else if(i==3){
dx--;
dw=2;
}
}
else if(st.w==1)
{
if(i==0){
dw=0;
}
else if(i==1){
dw=1;
}
else if(i==2){
dy++;
dw=0;
}
else if(i==3){
dw=1;
}
}
else if(st.w==2)
{
if(i==0){
dw=2;
}
else if(i==1){
dx++;
dw=0;
}
else if(i==2){
dw=2;
}
else if(i==3){
dw=0;
}
}
if(judge1(dx,dy,dw)&&!vis[dx][dy][dw])
{
vis[dx][dy][dw]=1;
ed.x=dx;
ed.y=dy;
ed.w=dw;
ed.step=ds;
Q.push(ed);
}
}
}
return 0;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.cpp","r",stdin);
#endif
while(~scanf("%d%d",&n,&m))
{
if(n==0&&m==0) break;
bool flag=0;
int sx,sy,sw;
clr(vis,0);
for(int i=0;i<n;i++){
scanf("%s",A[i]);
for(int j=0;j<m;j++){
if(A[i][j]=='X'){
if(!flag)
{
flag=1;
sx=i;
sy=j;
sw=0;
}
else{
if(judge(i-1,j)&&A[i-1][j]=='X')
sw=2;
else if(judge(i,j-1)&&A[i][j-1]=='X')
sw=1;
}
}
}
}
int cnt=slove(sx,sy,sw);
if(cnt)
printf("%d\n",cnt);
else
puts("Impossible");
}
return 0;
}