AcWing 立体推箱子

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;
	}
}
posted @ 2019-08-07 20:49  G_A_TS  阅读(302)  评论(0编辑  收藏  举报