题意:推箱子,有且只有3个箱子
思路:暴搜:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
using namespace std;
char map[9][9];
bool v[8][8][8][8][8][8][8][8];
int n,m;
int dx[]={0,0,-1,1};
int dy[]={-1,1,0,0};
struct cpoint{
int x,y;
};
struct node{
cpoint a[4];
int dis;
}st,en;
queue<node> que;
bool aim[9][8];
bool ok(node &e)
{
for(int i=0;i<3;i++)
{
if(!aim[e.a[i].x][e.a[i].y]) return false;
}
return true;
}
bool oor(int &x,int &y)
{
if(x<0||x>=n) return false;
if(y<0||y>=m) return false;
return true;
}
int solve()
{
memset(aim,false,sizeof(aim));
memset(v,false,sizeof(v));
for(int i=0;i<3;i++)
aim[en.a[i].x][en.a[i].y] = true;
st.dis=0;
while(!que.empty()) que.pop();
que.push(st);
node e,t;
while(!que.empty())
{
e = que.front();que.pop();
if(ok(e)) return e.dis;
if(v[e.a[0].x][e.a[0].y][e.a[1].x][e.a[1].y][e.a[2].x][e.a[2].y][e.a[3].x][e.a[3].y])
continue;
v[e.a[0].x][e.a[0].y][e.a[1].x][e.a[1].y][e.a[2].x][e.a[2].y][e.a[3].x][e.a[3].y]=true;
for(int i=0;i<4;i++)
{
int tx=e.a[3].x+dx[i],ty=e.a[3].y+dy[i];
if(!oor(tx,ty)||map[tx][ty]=='#') continue;
int j=0;
for(;j<3;j++)
if(e.a[j].x==tx&&e.a[j].y==ty) break;
if(j>=3)
{
t=e,t.a[3].x=tx,t.a[3].y=ty;
t.dis++;
que.push(t);
}
else
{
tx+=dx[i];ty+=dy[i];
if(!oor(tx,ty)||map[tx][ty]=='#') continue;
int k=0;
for(;k<3;k++)
if(e.a[k].x==tx&&e.a[k].y==ty) break;
if(k>=3)
{
t=e,t.a[j].x=e.a[j].x+dx[i],
t.a[j].y=e.a[j].y+dy[i];
t.a[3].x=e.a[j].x,t.a[3].y=e.a[j].y;
t.dis++;
que.push(t);
}
}
}
}return -1;
}
int main()
{
//freopen("in.txt","r",stdin);
while(~scanf("%d%d",&n,&m))
{
int cnt1=0,cnt2=0;
for(int i=0;i<n;i++)
{
scanf("%s",map[i]);
for(int j=0;j<m;j++)
{
if(map[i][j]=='X')
st.a[3].x=i,st.a[3].y=j;
else if(map[i][j]=='*')
st.a[cnt1].x=i,st.a[cnt1++].y=j;
else if(map[i][j]=='@')
en.a[cnt2].x=i,en.a[cnt2++].y=j;
if(map[i][j]!='#') map[i][j]='.';
}
}
printf("%d\n",solve());
}
return 0;
}