这题思路挺新的,,可是相比实现并不那么恶心
因为要求箱子的移动次数少 可以bfs,用三元组(x,y,dir)表示箱子在(x,y),dir是人所在的箱子的方向
因为在箱子移动次数少的基础上还要人移动尽可能少 所以每次判断人的移动时要再bfs一次(也就是bfs里套了一个bfs)
实际实现时我的队列里存储了6个量
q[x][0]:dir
q[x][1]:x
q[x][2]:y
q[x][3]:上一个状态(因为最后要求输出路径)
q[x][4]:箱子目前移动的步数
q[x][5]:人目前移动的步数
注意恶心至极的一点:每次第一次bfs到(x,y,dir)这个状态还不一定是最优的 要按照箱子的次数,人的次数来比较 特别的,对于acwing上“NSWE”的优先顺序要求 还要考虑推来的方向适不适合(以及注意判断当前对应的方向要按照“EWSN”来 因为上一步的方向比较靠后 要是靠前的更优先靠后的就不那么优先,可见代码)
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<queue>
using namespace std;
int n,m;
int sa,sb,ba,bb,ea,eb;
char s[25][25];
int dx[4]={1,-1,0,0},dy[4]={0,0,1,-1};
int lt[4]={'n'-'a','s'-'a','w'-'a','e'-'a'};
bool vis[25][25];
int vis2[25][25][4];
string str[25][25];
string bfs(int x,int y,int a,int b)
{
if(!(x>=1&&x<=n&&y>=1&&y<=m&&a>=1&&a<=n&&b>=1&&b<=m))return "!";
if(x==a&&y==b)return "";
memset(vis,0,sizeof(vis));
queue<pair<int,int> >qq;
while(!qq.empty())qq.pop();
qq.push(make_pair(x,y));
str[x][y]="";
while(!qq.empty())
{
int u=qq.front().first,v=qq.front().second;
qq.pop();
for(int i=0;i<4;++i)
{
int p=i;
i=i^1;
int tx=u+dx[i],ty=v+dy[i];
if(tx>=1&&tx<=n&&ty>=1&&ty<=m&&s[tx][ty]!='#'&&!vis[tx][ty])
{
str[tx][ty]=str[u][v]+char(lt[i^1]+'a');
if(tx==a&&ty==b)return str[tx][ty];
vis[tx][ty]=true;
qq.push(make_pair(tx,ty));
}
i=p;
}
}
return "!";
}
int q[5000][6],head,tail;
void trace(int x)
{
if(q[x][3]==-1)
{
s[ba][bb]='#';
cout<<bfs(sa,sb,q[x][1]+dx[q[x][0]],q[x][2]+dy[q[x][0]]);
s[ba][bb]='.';
return;
}
int k=q[x][3];
trace(k);
s[q[k][1]][q[k][2]]='#';
cout<<bfs(q[k][1]+dx[q[k][0]],q[k][2]+dy[q[k][0]],q[k][1]+dx[q[x][0]],q[k][2]+dy[q[x][0]]);
s[q[k][1]][q[k][2]]='.';
putchar(lt[q[x][0]]+'A');
}
void bfs2()
{
while(head<=tail)
{
int dir=q[head][0],x=q[head][1],y=q[head][2];
for(int i=0;i<4;++i)
{
int tx=x+dx[i],ty=y+dy[i];
int px=x-dx[i],py=y-dy[i];
if(px>=1&&px<=n&&py>=1&&py<=m&&s[px][py]!='#')
{
s[x][y]='#';
if(bfs(x+dx[dir],y+dy[dir],tx,ty)=="!")
{
s[x][y]='.';
continue;
}
int len=bfs(x+dx[dir],y+dy[dir],tx,ty).size();
s[x][y]='.';
if(vis2[px][py][i])
{
int k=vis2[px][py][i];
if(q[k][4]<q[head][4]+1||q[k][4]==q[head][4]+1&&q[k][5]<=q[head][5]+len||q[k][4]==q[head][4]+1&&q[k][5]==q[head][5]+len&&q[k][0]>i)continue;
else if(vis2[px][py][i]>head)
{
q[k][0]=i,q[k][3]=head,q[k][5]=q[head][5]+len;
continue;
}
}
vis2[px][py][i]=++tail;
q[tail][0]=i,q[tail][1]=px,q[tail][2]=py,q[tail][3]=head,q[tail][4]=q[head][4]+1,q[tail][5]=q[head][5]+len;
}
}
++head;
}
int ans=-1;
for(int i=0;i<4;++i)
{
if(vis2[ea][eb][i])
{
int k=vis2[ea][eb][i];
// printf("%c\n",lt[q[k][0]]+'A');
if(ans==-1||q[k][4]<q[ans][4]||q[k][4]==q[ans][4]&&q[k][5]<q[ans][5]||q[k][4]==q[ans][4]&&q[k][5]==q[ans][5]&&q[k][0]>q[ans][0])ans=k;
}
}
// printf("%c\n",lt[q[ans][0]]+'A');
if(ans==-1)printf("Impossible.\n");
else trace(ans),printf("\n");
printf("\n");
}
int main()
{
// freopen("pushing.in","r",stdin);
// freopen("pushing.out","w",stdout);
int tot=0;
while(scanf("%d%d",&n,&m)&&n)
{
printf("Maze #%d\n",++tot);
for(int i=1;i<=n;++i)
{
// i=i^1;
scanf("%s",s[i]+1);
for(int j=1;j<=m;++j)
{
if(s[i][j]=='S')sa=i,sb=j,s[i][j]='.';
else if(s[i][j]=='B')ba=i,bb=j,s[i][j]='.';
else if(s[i][j]=='T')ea=i,eb=j,s[i][j]='.';
}
}
head=1,tail=0;
memset(vis2,0,sizeof(vis2));
s[ba][bb]='#';
for(int i=0;i<4;++i)
{
int ta=ba+dx[i],tb=bb+dy[i];
if(s[ta][tb]=='#')continue;
if(bfs(sa,sb,ta,tb)!="!")
{
vis2[ba][bb][i]=++tail;
q[tail][0]=i,q[tail][1]=ba,q[tail][2]=bb,q[tail][3]=-1,q[tail][4]=0,q[tail][5]=bfs(sa,sb,ta,tb).size();
}
}
s[ba][bb]='.';
bfs2();
}
return 0;
}
附上一组数据,,我在自己做的时候很受用
input
1 7
SB....T
1 7
SB..#.T
7 11
###########
#T##......#
#.#.#..####
#....B....#
#.######..#
#.....S...#
###########
8 4
....
.##.
.#..
.#..
.#.B
.##S
....
###T
5 11
#T##......#
#.#.#..####
#....B....#
#.######..#
#.....S...#
4 5
##T..
.SB..
.#...
...##
7 8
........
.######.
.....T#.
#.#####.
#...BS..
#..#####
########
10 5
...##
.#.##
.#.##
.#.##
.#.##
.#.##
.#...
SB...
##...
##T..
1 3
STB
1 3
SBT
1 3
TBS
3 1
T
B
S
3 3
S..
.B.
T.#
12 14
S.#...........
.B.#..........
....#.........
#....#........
.#....#.......
..#....#......
...#....#.....
....#....#....
.....#....#...
......#....#..
.......#....#.
........#...T#
11 19
....#####..........
....#...#..........
....#...#..........
..###..B##.........
..#......#.........
###.#.##.#...######
#...#.##.#####T...#
#.................#
####..###.#S##....#
...#......#########
...########........
20 20
S...................
.##################.
..................#.
.#.#..............#.
.#.###########.#..#.
.#.#...........#..#.
.#.#..########.#..#.
.#.#.........#.#..#.
.#.########..#.#..#.
.#.#.....B...#.#....
.#.#.######..#.#..#.
.#.#.........#.#..#.
.#.#..########.#..#.
.#.#............#.#.
.#.#............#.#.
.#.#.############.#.
..................#.
.#................#.
.##################.
...................T
20 20
....................
.##################.
..................#.
#################.#.
................#.#.
.##############.#.#.
.#............#.#.#.
.#.##########.#.#.#.
.#.#........#.#.#.#.
.#.#.####...#.#.#.#.
.#.#.#..SB..#.#.#.#.
.#.#.#.##T..#.#.#.#.
.#.#.#.######.#.#.#.
.#.#.#........#.#.#.
.#.#.##########.#.#.
.#.#............#.#.
.#.##############.#.
.#................#.
.##################.
....................
20 20
....................
.##################.
..................#.
#################.#.
................#.#.
.##############.#.#.
.#............#.#.#.
.#.##########.#.#.#.
.#.#........#.#.#.#.
.#.#.####...#.#.#.#.
.#.#.#.SB...#.#.#.#.
.#.#.#..#.###.#.#.#.
.#.#.#.....##.#.#.#.
.#.#.#.T.#....#.#.#.
.#.#.##########.#.#.
.#.#............#.#.
.#.##############.#.
.#................#.
.##################.
....................
20 20
#################..#
SB.................#
################.#.#
.................#.#
..############.#.#.#
#..............#.#.#
#.#.########.#.#.#.#
#.#..........#.#.#.#
#.#.#.####.#.#.#.#.#
#.#.#......#.#.#.#.#
#.#.#.#.##.#.#.#.#.#
#.#.#.#.##T#.#.#.#.#
#.#.#.#........#.#.#
#.#.#.#.######.#.#.#
#.#.#............#.#
#.#.#.##########.#.#
#.#................#
#.#.##############..
#...................
#..#################
20 20
..#.................
.#SB.#...........##.
.#.#.#.#.#####.###..
.#.....#.....#...#..
.#.###.#...#.....#.#
.#...#####.#####.#..
.....#.....#.#...##.
.###.#.#...#.#......
.#...#.#.###.#.####.
.#.....#.....#...#..
.#.###.#...#.....#.#
.#...#####.#####.#..
.....#.....#.#...##.
.###.#.#...#.#......
.#...#.#.###.#.###.#
.#.....#.....#...#..
.#.###.#...#.....##.
.#...#####.#####.#..
...........#.......#
.#########...####..T
20 20
S...................
.T..................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
..................B.
....................
20 20
T...................
.S..................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
...................B
20 20
####################
#SB#################
####################
####################
####################
####################
####################
####################
####################
####################
####################
####################
####################
####################
####################
####################
####################
####################
####################
###################T
20 1
S
.
B
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
T
20 3
S..
##.
...
.##
...
##.
...
.##
...
##.
...
.##
...
##.
...
.##
...
##.
...
.BT
1 20
TB.................S
0 0
output的话就运行我的程序吧