用一个四维的vis数组表示这种状态出没出现过。每个维度分别表示坐标,颜色,方向。然后bfs。这里用到了优先队列。让用时最少的先走。
#include <iostream>
#include <cstring>
#include<cstdio>
#include <queue>
using namespace std ;
int cc,r;
char map[30][30];
int vis[30][30][5][4];
int sx,sy,tx,ty;int ans,flag=0;
int col[]={0,1,2,3,4};
int dd[]={0,1,2,3};//上下左右
int dx[]={-1,1,0,0};
int dy[]={0,0,-1,1};
struct node//这题让我学会了如何用优先队列
{
int x,y,s,d,c;
friend bool operator <(node a,node b)
{
return a.s>b.s;
}
};
bool isans(node n)
{
if(n.x==tx&&n.y==ty&&n.c==0)
return 1;
return 0;
}
void bfs()
{ //cout<<"d";
priority_queue<node>q;
node n1;
n1.x=sx;n1.y=sy;n1.c=0;n1.s=0;n1.d=0;
q.push(n1);
vis[sx][sy][n1.c][n1.d]=1;
while(!q.empty())
{//cout<<"e";
n1=q.top();
// cout<<n1.x<<" a"<<n1.y<<" "<<n1.c<<" "<<n1.d<<" "<<n1.s<<endl;
q.pop();
int x=n1.x,y=n1.y,c=n1.c,d=n1.d,s=n1.s;
int i;
for(i=0;i<4;++i)
{ //cout<<i<<endl;
if(i!=d)
{
if((i==0&&d==1)||(i==1&&d==0)||(i==2&&d==3)||(i==3&&d==2))
{
n1.x=x;n1.y=y;
n1.c=c;n1.s=s+2;n1.d=i;
//cout<<n1.x<<" a"<<n1.y<<" "<<n1.c<<" "<<n1.d<<map[n1.x][n1.y]<<vis[n1.x][n1.y][n1.c][n1.d]<<endl;
if(n1.x>=0&&n1.x<r&&n1.y>=0&&n1.y<cc&&map[n1.x][n1.y]!='#'&&vis[n1.x][n1.y][n1.c][n1.d]==0)
{//cout<<"ok";
q.push(n1);
if(isans(n1))
{
ans=n1.s;
flag=1;
return;
}
vis[n1.x][n1.y][n1.c][n1.d]=1;
//cout<<n1.x<<" "<<n1.y<<" "<<n1.c<<" "<<n1.d<<endl;
}
}
else
{
n1.x=x;n1.y=y;
n1.c=c;n1.s=s+1;n1.d=i;
//cout<<n1.x<<" b"<<n1.y<<" "<<n1.c<<" "<<n1.d<<map[n1.x][n1.y]<<vis[n1.x][n1.y][n1.c][n1.d]<<endl;
if(n1.x>=0&&n1.x<r&&n1.y>=0&&n1.y<cc&&map[n1.x][n1.y]!='#'&&vis[n1.x][n1.y][n1.c][n1.d]==0)
{q.push(n1);
if(isans(n1))
{
ans=n1.s;
flag=1;
return;
}
vis[n1.x][n1.y][n1.c][n1.d]=1;
}
}
}
if(i==d)
{
n1.x=x+dx[i];n1.y=y+dy[i];
n1.c=(c+1)%5;n1.s=s+1;n1.d=d;
//cout<<n1.x<<" c"<<n1.y<<" "<<n1.c<<" "<<n1.d<<map[n1.x][n1.y]<<vis[n1.x][n1.y][n1.c][n1.d]<<endl;
if(n1.x>=0&&n1.x<r&&n1.y>=0&&n1.y<cc&&map[n1.x][n1.y]!='#'&&vis[n1.x][n1.y][n1.c][n1.d]==0)
{q.push(n1);
if(isans(n1))
{
ans=n1.s;
flag=1;
return;
}
vis[n1.x][n1.y][n1.c][n1.d]=1;
//cout<<n1.x<<" "<<n1.y<<" "<<n1.c<<" "<<n1.d<<endl;
}
}
}
}
return ;
}
int main()
{ int casei=1;
while(scanf("%d%d",&r,&cc))
{getchar();
flag=0;
memset(vis,0,sizeof(vis));
if(r==0&&cc==0)break;
if(casei!=1)printf("\n");
int i,j;
for(i=0;i<r;++i)
{
for(j=0;j<cc;++j)
{
scanf("%c",&map[i][j]);
if(map[i][j]=='S')sx=i,sy=j;
if(map[i][j]=='T')tx=i,ty=j;
}
getchar();
}
bfs();
printf("Case #%d\n",casei++);
if(flag)
{
printf("minimum time = %d sec\n",ans);
}
else
printf("destination not reachable\n");
}
return 0 ;
}