搜索这种东西只要写之前规划得当还是蛮顺手的。。
mark[x1][y1][x2][y2]表示小人在(x1,y1) 盒子在(x2,y2)这种状态是否到过。
剩下的就是优先队列 + bfs 了,另外开一个栈记录前驱以输出路径。
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <cmath>
#include <stack>
#include <map>
#pragma comment(linker, "/STACK:1024000000");
#define EPS (1e-8)
#define LL long long
#define ULL unsigned long long
#define _LL __int64
#define _INF 0x3f3f3f3f
#define Mod 9999991
using namespace std;
char Map[24][24];
int mark[22][22][22][22];
struct N
{
int x1,x2,y1,y2;
};
struct Q
{
int ans,x1,y1,x2,y2,pre;
int ans2,site;
bool operator < (const Q &a)const{
return (a.ans2 < ans2 || (a.ans2 == ans2 && a.ans < ans));
}
}q[200000];
bool Judge(Q f)
{
if(abs(f.x1-f.x2) + abs(f.y1-f.y2) <= 1)
return true;
return false;
}
int jx[] = {-1, 1, 0, 0};
int jy[] = { 0, 0,-1, 1};
void Out(int site,Q f)
{
if(site == -1)
return ;
Out(q[site].pre,q[site]);
Q t = q[site];
if(t.x1 == f.x1)
{
if(t.y1+1 == f.y1)
{
if(t.x2 == f.x2 && t.y2+1 == f.y2)
{
printf("E");
}
else
{
printf("e");
}
}
else if(t.y1-1 == f.y1)
{
if(t.x2 == f.x2 && t.y2-1 == f.y2)
{
printf("W");
}
else
{
printf("w");
}
}
}
else if(t.y1 == f.y1)
{
if(t.x1+1 == f.x1)
{
if(t.y2 == f.y2 && t.x2+1 == f.x2)
{
printf("S");
}
else
{
printf("s");
}
}
else if(t.x1-1 == f.x1)
{
if(t.y2 == f.y2 && t.x2-1 == f.x2)
{
printf("N");
}
else
{
printf("n");
}
}
}
}
void bfs(N s,int n,int m)
{
memset(mark,-1,sizeof(mark));
mark[s.x1][s.y1][s.x2][s.y2] = 0;
priority_queue<Q> pq;
Q f,t;
int S = 0,E = 0;
f.ans = 0;
f.ans2 = 0;
f.pre = -1;
f.x1 = s.x1;
f.x2 = s.x2;
f.y1 = s.y1;
f.y2 = s.y2;
f.site = 0;
q[E++] = f;
pq.push(f);
while(pq.empty() == false)
{
f = pq.top();
pq.pop();
if(Map[f.x2][f.y2] == 'T')
{
Out(f.pre,f);
puts("");
return ;
}
t.pre = f.site;
t.ans = f.ans+1;
for(int i = 0 ;i < 4; ++i)
{
t.x1 = f.x1 + jx[i];
t.y1 = f.y1 + jy[i];
t.x2 = f.x2;
t.y2 = f.y2;
if(1 <= t.x1 && t.x1 <= n && 1 <= t.y1 && t.y1 <= m && Map[t.x1][t.y1] != '#' && -1 == mark[t.x1][t.y1][t.x2][t.y2])
{
if(t.x1 != t.x2 || t.y1 != t.y2)
{
mark[t.x1][t.y1][t.x2][t.y2] = t.ans;
t.site = E;
t.ans2 = f.ans2;
q[E++] = t;
pq.push(t);
}
else
{
t.x2 = f.x2 + jx[i];
t.y2 = f.y2 + jy[i];
if(1 <= t.x2 && t.x2 <= n && 1 <= t.y2 && t.y2 <= m && Map[t.x2][t.y2] != '#' && -1 == mark[t.x1][t.y1][t.x2][t.y2])
{
t.ans2 = f.ans2+1;
t.site = E;
q[E++] = t;
pq.push(t);
mark[t.x1][t.y1][t.x2][t.y2] = t.ans;
}
}
}
}
}
printf("Impossible.\n");
}
int main()
{
int i,j,n,m;
int icase = 1;
while(scanf("%d %d",&n,&m) && (n||m))
{
for(i = 1;i <= n;++i)
scanf("%s",Map[i]+1);
N s;
for(i = 1;i <= n;++i)
{
for(j = 1;j <= m; ++j)
{
if(Map[i][j] == 'S')
s.x1 = i,s.y1 = j;
else if(Map[i][j] == 'B')
s.x2 = i,s.y2 = j;
}
}
printf("Maze #%d\n",icase++);
bfs(s,n,m);
puts("");
}
return 0;
}