【ybt】【基算 广搜 课过 例3】立体推箱子

立体推箱子

题目链接:立体推箱子


题目描述

题目2
题目2

解题思路

这道题很容易可以想到是广搜。

难点在于如何表示出躺下的情况。

但其实只需要记录两个点中的一个,然后用一个状态变量就可以表示出一整个箱子。

主要是状态的转移不太好推,要有耐心。

其他的注意一些细节就可以了。

code

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

const int xn[4][5]={
    
    {
    
    },{
    
    0,-1,0,2,0},{
    
    0,-1,0,1,0},{
    
    0,-2,0,1,0}};
const int yn[4][5]={
    
    {
    
    },{
    
    0,0,2,0,-1},{
    
    0,0,1,0,-2},{
    
    0,0,1,0,-1}};
const int tn[4][5]={
    
    {
    
    },{
    
    0,3,2,3,2},{
    
    0,2,1,2,1},{
    
    0,1,3,1,3}};

int n,m;
int ex,ey;
int v[510][510][5];
char a[510][510];

struct abc{
    
    
	int x,y,t,s;
}f[2500010];

bool check(int x,int y,int t)
{
    
    
	if(x<1||x>n||y<1||y>m)
		return 0;
	if(t==1)
	{
    
    
		if(a[x][y]=='E')
			return 0;
		if(a[x][y]=='#')
			return 0;
	}
	if(t==2)
	{
    
    
		if(a[x][y]=='#')
			return 0;
		if(a[x][y-1]=='#')
			return 0;
	}
	if(t==3)
	{
    
    
		if(a[x][y]=='#')
			return 0;
		if(a[x-1][y]=='#')
			return 0;
	}
	return 1; 
}

bool bfs()
{
    
    
	int hd=0,tl=1;
	while(hd<tl)
	{
    
    
		hd++;
		for(int i=1;i<=4;i++)
		{
    
    
			int x=f[hd].x+xn[f[hd].t][i];
			int y=f[hd].y+yn[f[hd].t][i];
			int t=tn[f[hd].t][i];
			if(check(x,y,t)&&!v[x][y][t])
			{
    
    
				v[x][y][t]=1;
				f[++tl]=(abc){
    
    x,y,t,f[hd].s+1};
				if(x==ex&&y==ey&&t==1)
				{
    
    
					cout<<f[tl].s<<endl;
					return 0;
				}
			}
		}
	}
	return 1;
}

void star()
{
    
    
	memset(v,0,sizeof(v));
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
		{
    
    
			if(a[i][j]=='X')
			{
    
    
				f[1].x=i,f[1].y=j,f[1].s=0;
				if(a[i][j-1]=='X')
					f[1].t=2;
				else if(a[i-1][j]=='X')
					f[1].t=3;
				else
					f[1].t=1;
				v[i][j][f[1].t]=1;
			}
			if(a[i][j]=='O')
				ex=i,ey=j;
		}
}

int main()
{
    
    
	while(cin>>n>>m)
	{
    
    
		if(n==0&&m==0)
			return 0;
		for(int i=1;i<=n;i++)
		{
    
    
			for(int j=1;j<=m;j++)
			{
    
    
				a[i][j]=getchar();
				while(a[i][j]!='#'&&a[i][j]!='.'&&a[i][j]!='X'&&a[i][j]!='E'&&a[i][j]!='O')
					a[i][j]=getchar();
			}
		}
		star();
		if(bfs())
			cout<<"Impossible"<<endl;
	}	
}

猜你喜欢

转载自blog.csdn.net/SSL_guyixin/article/details/112384448