經典的推箱子。。
寫的真好。。
開始還沒看明白,抄了一遍懂了。
#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
bool map[10][10][5];
int d[4][2]={-1,0,0,-1,1,0,0,1};
char maze[10][10],b[10][10];
int tx,ty,px,py;
struct point
{
int x,y;
};
struct node
{
point box[3];
int px,py;
int step;
node()
{
memset(box,0,sizeof(box));
px=py=0;
step=0;
}
node & operator=(const node &t1)
{
memcpy(box,t1.box,sizeof(box));
//memcpy(isover,t1.box,sizeof(isover));
px=t1.px;
py=t1.py;
step=t1.step;
return * this;
}
}cur,tmp;
bool vis[8][8][8][8][8][8][8][8];
bool aim[9][8];
int n,m;
bool ok(node &e)
{
for(int i=0;i<3;i++)
{
if(!aim[e.box[i].x][e.box[i].y])
return 0;
}
return 1;
}
bool oor(int x,int y)
{
if(x<0 || x>=n) return 0;
if(y<0 || y>=m) return 0;
return 1;
}
node start,en;
point hole[3];
queue<node>qu;
int bfs()
{
memset(aim,0,sizeof(aim));
memset(vis,0,sizeof(vis));
for(int i=0;i<3;i++)
aim[hole[i].x][hole[i].y]=1;
start.step=0;
while(!qu.empty()) qu.pop();
//queue<node>qu;
qu.push(start);
//node cur,tmp;
while(!qu.empty())
{
cur=qu.front(); qu.pop();
if(ok(cur)) return cur.step;
if(vis[cur.box[0].x][cur.box[0].y][cur.box[1].x][cur.box[1].y][cur.box[2].x][cur.box[2].y][cur.px][cur.py])
continue;
vis[cur.box[0].x][cur.box[0].y][cur.box[1].x][cur.box[1].y][cur.box[2].x][cur.box[2].y][cur.px][cur.py]=1;
for(int i=0;i<4;i++)
{
int tx=cur.px+d[i][0];
int ty=cur.py+d[i][1];
if(!oor(tx,ty) || maze[tx][ty]=='#')
continue;
int j=0;
for(;j<3;j++)
if(cur.box[j].x==tx && cur.box[j].y==ty)
break;
//人要走的下一步沒有箱子
if(j>=3)
{
tmp=cur;
tmp.px=tx;
tmp.py=ty;
tmp.step++;
qu.push(tmp);
}
else
{//有箱子,tx,ty是箱子的座標
tx+=d[i][0]; ty+=d[i][1];
if(!oor(tx,ty) || maze[tx][ty]=='#')
continue;
int k=0;
for(;k<3;k++)
if(cur.box[k].x==tx && cur.box[k].y==ty)
break;
if(k>=3)
{
tmp=cur;
tmp.box[j].x=cur.box[j].x+d[i][0];
tmp.box[j].y=cur.box[j].y+d[i][1];
tmp.px=cur.box[j].x, tmp.py=cur.box[j].y;
tmp.step++;
qu.push(tmp);
}
}
}
}
return -1;
}
int main()
{
int t;
while(~scanf("%d %d",&n,&m))
{
int ind=0,ind2=0;
//memset(ishole,0,sizeof(ishole));
for(int i=0;i<n;i++)
{
scanf("%s",&maze[i]);
for(int j=0;j<m;j++)
{
if(maze[i][j]=='*')//箱子座標
start.box[ind].x=i,start.box[ind++].y=j;
else if(maze[i][j]=='@')//目標座標
hole[ind2].x=i,hole[ind2++].y=j;
else if(maze[i][j]=='X')//人的座標
start.px=i,start.py=j;
if(maze[i][j]!='#')
maze[i][j]='.';
}
}
printf("%d\n",bfs());
}
return 0;
}