//2478723 2010-05-21 23:28:53 Accepted 1732 156MS 20656K 2718 B C++
//用8维的hash标记人坐标3个箱子的坐标 主要是人前方为箱子箱子前面再出现箱子容易漏掉考虑
//这里bool 的hash可以比int少4倍的空间 开成int会MLE
#include<iostream>
#include<queue>
#include<cstdio>
#include<string>
using namespace std;
struct node{
int mx,my;
int bx[4],by[4];
int step;
};
node s;
int dir[4][2] = { { 1 , 0 },{ -1 , 0 },{ 0 , -1 },{ 0 , 1 } };
char map[10][10];
bool hash[8][8][8][8][8][8][8][8];
int m,n,nbox,lianxiang;
void bfs(node s)
{
memset(hash,true,sizeof(hash));
queue<node>q;
int i,j;
node N,P;
N = s;
q.push(N);
while(!q.empty())
{
N = q.front();
q.pop();
if(map[ N.bx[1] ][ N.by[1]] == '@' && map[ N.bx[2] ][ N.by[2]] == '@' && map[ N.bx[3] ][ N.by[3]] == '@')
{
printf("%d/n",N.step);
return;
}
for( i = 0; i < 4; i++)
{
P = N;
P.mx = N.mx + dir[i][0];
P.my = N.my + dir[i][1];
P.step = N.step + 1;
if(map[P.mx][P.my] != '#' && P.mx >= 0 && P.my >=0 && P.mx < n && P.my < m)
{
nbox = -1 ;
if(P.mx == P.bx[1] && P.my == P.by[1]) //一开始用s的箱子坐标了 忘了搜索是会变的
{
nbox = 1;
P.bx[1] = N.bx[1] + dir[i][0];
P.by[1] = N.by[1] + dir[i][1];
}
else if(P.mx == P.bx[2] && P.my == P.by[2])
{
nbox = 2;
P.bx[2] = N.bx[2] + dir[i][0];
P.by[2] = N.by[2] + dir[i][1];
}
else if(P.mx == P.bx[3] && P.my == P.by[3])
{
nbox = 3;
P.bx[3] = N.bx[3] + dir[i][0];
P.by[3] = N.by[3] + dir[i][1];
}
if(nbox != -1) //和前面一样的错误一开始直接用 map[P.mx][P.my] == '*'了
{ //忘了箱子在搜索时候的坐标是和地图中的不同的
if(P.bx[nbox] >= 0 && P.by[nbox] >= 0 && P.bx[nbox] < n && P.by[nbox] < m && map[P.bx[nbox]][P.by[nbox]] != '#')
{
bool bisok = true;
for(j = 1; j < 4; j++)
if(j != nbox && P.bx[nbox] == P.bx[j] && P.by[nbox] == P.by[j])
bisok = false; //箱子的下一步再次出现其它箱子的情况
if(hash[ P.mx ][ P.my ][ P.bx[1] ][ P.by[1] ][ P.bx[2] ][ P.by[2] ][ P.bx[3] ][ P.by[3] ] && bisok)
{
hash[ P.mx ][ P.my ][ P.bx[1] ][ P.by[1] ][ P.bx[2] ][ P.by[2] ][ P.bx[3] ][ P.by[3] ] = false;
q.push(P);
}
}
}
else
{
if(hash[ P.mx ][ P.my ][ P.bx[1] ][ P.by[1] ][ P.bx[2] ][ P.by[2] ][ P.bx[3] ][ P.by[3] ] == true)
{
hash[ P.mx ][ P.my ][ P.bx[1] ][ P.by[1] ][ P.bx[2] ][ P.by[2] ][ P.bx[3] ][ P.by[3] ] = false;
q.push(P);
}
}
}
}//for
}
printf("-1/n");
return;
}
void main()
{
int i,j,count;;
while(scanf("%d%d",&n,&m) != EOF)
{
count = 1;
for(i = 0; i < n; i++)
scanf("%s",&map[i]);
for(i = 0; i < n; i++)
for(j = 0; j < m; j++)
{
if(map[i][j] == 'X')
{
s.mx = i;
s.my = j;
}
else if(map[i][j] == '*')
{
s.bx[count] = i;
s.by[count] = j;
count++;
}
}
s.step = 0;
hash[s.mx][s.my][s.bx[1]][s.by[1]][s.bx[2]][s.by[2]][s.bx[3]][s.by[3]] = false;
bfs(s);
}
}
hdu 1732推箱子
最新推荐文章于 2018-07-22 09:25:10 发布