链接:http://acm.hdu.edu.cn/showproblem.php?pid=1732
题意:类似推箱子游戏,三个箱子,三个目的地,求出人把三个箱子都推到目的地的最小步数,若没法完成就输出-1。
本来是个难度不大的BFS,但是我习惯把vis定义成int,结果不停地超内存,唉,以后还是要改用bool的时候用bool
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
using namespace std;
struct node
{
int x,y;
int step;
int bx[3],by[3];
};
char map[9][9];
bool vis[8][8][8][8][8][8][8][8];//用int超内存
int dir[4][2]={0,1,1,0,0,-1,-1,0};
int n,m;
node pre;
queue<node> q;
int is_ok(node &a)
{
int i;
for(i=0;i<3;i++) if(map[a.bx[i]][a.by[i]]!='@') return 0;
return 1;
}
int check(int x,int y)
{
if(x<0||x>=n||y<0||y>=m||map[x][y]=='#') return 0;
return 1;
}
int bfs()
{
while(!q.empty()) q.pop();
memset(vis,0,sizeof(vis));
pre.step=0;
q.push(pre);
node next;
int i,j,k;
while(!q.empty())
{
pre=q.front();
q.pop();
if(vis[pre.x][pre.y][pre.bx[0]][pre.by[0]][pre.bx[1]][pre.by[1]][pre.bx[2]][pre.by[2]]) continue;
vis[pre.x][pre.y][pre.bx[0]][pre.by[0]][pre.bx[1]][pre.by[1]][pre.bx[2]][pre.by[2]]=true;
for(i=0;i<4;i++)
{
next=pre;
next.x+=dir[i][0];
next.y+=dir[i][1];
next.step++;
if(!check(next.x,next.y)) continue;
for(j=0;j<3;j++) if(next.x==next.bx[j]&&next.y==next.by[j]) break;
if(j>=3)
{
q.push(next);
}
else
{
int xx=next.x+dir[i][0],yy=next.y+dir[i][1];
if(!check(xx,yy)) continue;
for(k=0;k<3;k++) if(xx==next.bx[k]&&yy==next.by[k]) break;
if(k<3) continue;
next.bx[j]=xx,next.by[j]=yy;
if(is_ok(next)) return next.step;
q.push(next);
}
}
}
return -1;
}
int main()
{
int i,j;
while(scanf("%d%d",&n,&m)!=EOF)
{
int up=0;
for(i=0;i<n;i++)
{
scanf("%s",map[i]);
for(j=0;j<m;j++)
{
if(map[i][j]=='X')
pre.x=i,pre.y=j;
else if(map[i][j]=='*')
pre.bx[up]=i,pre.by[up]=j,up++;
}
}
printf("%d\n",bfs());
}
return 0;
}