[Ybt] [Caso 3 de clase de búsqueda amplia de cálculo básico] 3D Sokoban

Sokoban tridimensional

Enlace de tema: Sokoban


Descripción del Título

Tema 2
Tema 2

Ideas para resolver problemas

Esta pregunta se puede considerar fácilmente como Guangsou.

La dificultad radica en cómo expresar la situación acostada.

Pero, de hecho, solo necesita registrar uno de los dos puntos y luego usar una variable de estado para representar un cuadro completo.

La razón principal es que la transición de estado no es fácil de impulsar, así que tenga paciencia.

Otros prestan atención a algunos detalles.

código

#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;
	}	
}

Supongo que te gusta

Origin blog.csdn.net/SSL_guyixin/article/details/112384448
Recomendado
Clasificación