题目大意
你的任务是操作一个 1 *1 *2 的长方体。
把它从x挪到o,每一次操作4个方向,沿棱滚90°,有#地不能走,E地不能立着,x可能有2个即开始时可以为横着或竖着,但o只有一个,多组数据,给出棋盘大小和棋盘.
思路
如果是立着的,以0表示状态,x,y为坐标,横着的,以1表示,x,y为左边的坐标,竖着的,以2表示,x,y为上面坐标,bfs(某度优先搜索)完成。
code:
#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
char a[502][502];
bool q[502][502][3];
int n,m,q2[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
struct f{
int x,y,f,s;
} o,o2,o3;
queue<f> p,p2;
void y()
{
memset(q,0,sizeof(q));
for (int i=1;i<=n;i++)
{
for (int j=1;j<=m;j++)
{
if (a[i][j]=='X')
{
o.x=i,o.y=j,o.f=0;
if (a[i+1][j]=='X') o.f=1;
if (a[i][j+1]=='X') o.f=2;
o.s=0;
q[i][j][o.f]=1;
p.push(o);
return;
}
}
}
}
void bfs()
{
while (p.size())
{
o=p.front();
p.pop();
for (int i=0;i<4;i++)
{
int dx=o.x+q2[i][0],dy=o.y+q2[i][1],df;
if (o.f==1&&i==1) dx++;
if (o.f==2&&i==3) dy++;
if (o.f==0)
{
if (i==0) dx--;
if (i==2) dy--;
}
if (o.f==1)
{
df=1;
if (i<2) df=0;
}
if (o.f==2)
{
df=2;
if (i>1) df=0;
}
if (o.f==0)
{
df=1;
if (i>1) df=2;
}
if (dx<1||dy<1||dx>n||dy>m) continue;
if (df==0&&a[dx][dy]=='O')
{
cout<<o.s+1<<endl;
return;
}
if (q[dx][dy][df]==1) continue;
if (a[dx][dy]=='#') continue;
if (df==1&&a[dx+1][dy]=='#') continue;
if (df==2&&a[dx][dy+1]=='#') continue;
if (df==0&&a[dx][dy]=='E') continue;
o2.x=dx,o2.y=dy,o2.f=df,o2.s=o.s+1;
p.push(o2);
q[dx][dy][df]=1;
}
}
cout<<"Impossible"<<endl;
return;
}
int main()
{
cin>>n>>m;
while (n!=0||m!=0)
{
p=p2;
for (int i=1;i<=n;i++)
{
for (int j=1;j<=m;j++)
{
cin>>a[i][j];
}
}
y();
bfs();
cin>>n>>m;
}
return 0;
}