题意:
将箱子推到目标位置,要求推箱子的次数最少
思路:
1.纯bfs
2.优先队列
3.A*
优先队列
注意记录路径用字符数组(实测1094MS)不用字符串(实测超时)
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <string>
#include <cmath>
#include <queue>
using namespace std;
const int M=25;
bool f[M][M];
bool b[M][M][M][M];
char a[M];
int d[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
char dd[4][2]={{'n','N'},{'s','S'},{'w','W'},{'e','E'}};
struct f1
{
int x,y,sx,sy;
char c[801];
int t,tt;
bool operator <(const f1 &q) const
{
return (t>q.t)||(t==q.t&&tt>q.tt);
}
}p,tmp;
int i,j,k,n,m,tot,xx,yy;
bool FF(int x,int y)
{
if(x>=1&&x<=n&&y>=1&&y<=m) return true;
return false;
}
void bfs()
{
priority_queue <f1> q;
b[p.x][p.y][p.sx][p.sy]=1;
p.c[0]='\0';
p.t=0,p.tt=0;
q.push(p);
while(!q.empty())
{
p=q.top();
q.pop();
//cout<<p.c<<endl;
for(i=0;i<=3;i++)
{
tmp.x=p.x+d[i][0];
tmp.y=p.y+d[i][1];
if(tmp.x==p.sx&&tmp.y==p.sy)
{
tmp.sx=p.sx+d[i][0];
tmp.sy=p.sy+d[i][1];
if(FF(tmp.sx,tmp.sy)&&f[tmp.sx][tmp.sy]&&!b[tmp.x][tmp.y][tmp.sx][tmp.sy])
{
b[tmp.x][tmp.y][tmp.sx][tmp.sy]=1;
for(int k=0;k<p.tt;k++)
tmp.c[k]=p.c[k];
tmp.c[p.tt]=dd[i][1];
tmp.t=p.t+1;
tmp.tt=p.tt+1;
q.push(tmp);
if(tmp.sx==xx&&tmp.sy==yy)
{
tmp.c[tmp.tt]='\0';
printf("%s\n\n",tmp.c);
return;
}
}
}
else if(FF(tmp.x,tmp.y)&&f[tmp.x][tmp.y])
{
//cout<<x<<' '<<y<<endl;
tmp.sx=p.sx;
tmp.sy=p.sy;
if(!b[tmp.x][tmp.y][p.sx][p.sy])
{
b[tmp.x][tmp.y][p.sx][p.sy]=1;
for(int k=0;k<p.tt;k++)
tmp.c[k]=p.c[k];
tmp.c[p.tt]=dd[i][0];
tmp.t=p.t;
tmp.tt=p.tt+1;
q.push(tmp);
}
}
}
}
printf("Impossible.\n\n");
}
int main()
{
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
while(~scanf("%d %d",&n,&m))
{
if(m+n==0) break;
tot++;
printf("Maze #%d\n",tot);
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
{
f[i][j]=1;
for(int k=1;k<=n;k++)
for(int o=1;o<=m;o++)
b[i][j][k][o]=0;
}
gets(a);
for(i=1;i<=n;i++)
{
gets(a);
for(j=0;j<m;j++)
{
if(a[j]=='#') f[i][j+1]=0;
else if(a[j]=='T') { xx=i; yy=j+1; }
else if(a[j]=='S') { p.x=i; p.y=j+1; }
else if(a[j]=='B') { p.sx=i; p.sy=j+1; }
}
}
bfs();
}
fclose(stdin);
fclose(stdout);
}