思路:
典型的bfs + 狀壓啊,一個入口出口,還要拿到地圖中多個東西,而且同一個點重複走的話不好標記,這時候就標記狀態啊/。。
md,退役垃圾狗。。。
答案 :48
PS:
這裏走回出口沒必要在跑一遍bfs,只需要走到出口時判斷一下是否所有箱子都拿到了即可。
#include <bits/stdc++.h>
using namespace std;
int a[15][11] = {
{0,0,0,0,0,0,0,0,0,0,0},
{0,1,0,0,0,0,0,0,2,0,0},
{0,0,0,0,-1,0,0,2,0,0,0},
{0,0,-1,0,0,2,0,0,-1,0,0},
{0,0,2,0,0,0,-1,0,0,2,0},
{0,0,-1,0,0,2,0,-1,0,0,0},
{0,0,0,-1,0,0,0,0,-1,0,0},
{0,0,0,0,0,0,-1,0,0,2,0},
{0,0,-1,0,-1,0,0,2,0,0,0},
{0,0,2,0,0,0,0,-1,-1,0,0},
{0,0,0,-1,0,0,-1,2,0,0,0}
};
int go[4][2] = {0,1,1,0,0,-1,-1,0};
struct node
{
int x,y,sta,step;
node(int xx = 0,int yy = 0,int state = 0,int s = 0)
{
x = xx,y = yy,sta = state,step = s;
}
};
bool vis[20][20][1050];
int num[20][20];
int get_sta(int x,int y,int cur)
{
int p[20];
for(int i = 0;i < 10;++i)
{
p[i] = (cur >> i) & 1;
}
p[num[x][y]] = 1;
int now = 0;
for(int i = 9;i >= 0;--i)
now = now * 2 + p[i];
return now;
}
int bfs(int st,int dt)
{
memset(vis,0,sizeof vis);
queue<node>Q;
while(!Q.empty()) Q.pop();
Q.push(node(st,dt,0,0));
vis[st][dt][0] = 1;
while(!Q.empty())
{
node q = Q.front();Q.pop();
if(q.x == 1 && q.y == 1 && q.sta == 1023)
return q.step;
for(int i = 0;i < 4;++i)
{
int tx = q.x + go[i][0];
int ty = q.y + go[i][1];
int sta = q.sta;
if(a[tx][ty] == 2)
{
sta = get_sta(tx,ty,sta);
}
if(tx < 1 || ty < 1|| tx > 10 || ty > 10 || a[tx][ty] == -1 || vis[tx][ty][sta])
continue;
vis[tx][ty][sta] = 1;
Q.push(node(tx,ty,sta,q.step + 1));
}
}
return -1;
}
int main()
{
memset(num,-1,sizeof num);
int cnt = 0;
for(int i = 1;i <= 10;++i)
{
for(int j = 1;j <= 10;++j)
{
if(a[i][j] == 2)
{
//printf("%d %d\n",i,j);
num[i][j] = cnt++;
}
}
}
//cout << cnt << endl;
cout << bfs(1,1) << endl;
return 0;
}