状态比较多,根据题目描述来看,是可以原地打转的,也是可以反向的,所以状态就是位置+颜色+方向,bfs,就是写起来比较糟心
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int maxn=30;
char gra[maxn][maxn];
int sx,sy,tx,ty;
int n,m;
int pos[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
struct point
{
int x,y,step,col,dir;
bool operator <(const point &a) const
{
return step>a.step;
}
};
bool vis[maxn][maxn][10][10];
bool check(int x,int y)
{
if(x>=1&&x<=n&&y>=1&&y<=m) return 1;
else return 0;
}
int bfs(int x,int y)
{
point u;
u.x=x,u.y=y,u.step=0,u.col=0,u.dir=0;
vis[u.x][u.y][0][0]=1;
priority_queue<point>q;
q.push(u);
while(!q.empty())
{
u=q.top();
q.pop();
if(u.x==tx&&u.y==ty&&u.col==0) return u.step;
point v;
for(int i=0;i<4;i++)
{
if(u.dir==i)
{
v.x=u.x+pos[i][0];
v.y=u.y+pos[i][1];
v.dir=u.dir;
v.col=(u.col+1)%5;
v.step=u.step+1;
if((!vis[v.x][v.y][v.col][v.dir])&&check(v.x,v.y)&&gra[v.x][v.y]!='#')
{
q.push(v);
vis[v.x][v.y][v.col][v.dir]=1;
}
}
else
{
if(u.dir+i==1||u.dir+i==5) v.step=u.step+2;
else v.step=u.step+1;
v.dir=i;
v.x=u.x;
v.y=u.y;
v.col=u.col;
if(!vis[v.x][v.y][v.col][v.dir])
{
vis[v.x][v.y][v.col][v.dir]=1;
q.push(v);
}
}
}
}
return -1;
}
int main()
{
//freopen("in.txt","r",stdin);
int temp=1;
while(~scanf("%d%d",&n,&m)&&n&&m)
{
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
for(int k=0;k<10;k++)
for(int l=0;l<10;l++) vis[i][j][k][l]=0;
cin>>gra[i][j];
if(gra[i][j]=='S') sx=i,sy=j;
if(gra[i][j]=='T') tx=i,ty=j;
}
int ans=bfs(sx,sy);
if(temp!=1) printf("\n");
printf("Case #%d\n",temp);
temp++;
if(ans==-1) printf("destination not reachable\n");
else printf("minimum time = %d sec\n",ans);
}
return 0;
}